${COMMON_FOLDER}/utils/c-array.hpp)
## Setup target ################################################################
-SET(CLI_CODENAME "${PROJECT_NAME}-cli")
+SET(CLI_CODENAME "vsm")
ADD_EXECUTABLE(${CLI_CODENAME} ${cli_SRCS})
## Readline detection ##########################################################
INCLUDE_DIRECTORIES(${COMMON_FOLDER})
TARGET_LINK_LIBRARIES(${CLI_CODENAME} ${PROJECT_NAME}-client ${LIB_DEPS_LIBRARIES} Ipc)
-CONFIGURE_FILE(support/vasum-cli-completion.sh.in
- ${CMAKE_BINARY_DIR}/vasum-cli-completion.sh
+CONFIGURE_FILE(support/vsm-completion.sh.in
+ ${CMAKE_BINARY_DIR}/vsm-completion.sh
@ONLY)
## Install #####################################################################
INSTALL(TARGETS ${CLI_CODENAME} DESTINATION bin)
-INSTALL(FILES ${CMAKE_BINARY_DIR}/vasum-cli-completion.sh
+INSTALL(FILES ${CMAKE_BINARY_DIR}/vsm-completion.sh
DESTINATION ${SYSCONF_INSTALL_DIR}/bash_completion.d)
#include <iomanip>
#include <algorithm>
#include <vector>
-#include <fcntl.h>
#include <cassert>
+#include <fcntl.h>
#include <linux/if_link.h>
#include <arpa/inet.h>
#include <unistd.h>
+#include <string.h>
using namespace std;
return name;
}
-std::string zoneToString(const VsmZone& zone)
-{
- std::string out = std::string("Name: ") + vsm_zone_get_id(zone)
- + std::string("\nTerminal: ") + std::to_string(vsm_zone_get_terminal(zone))
- + std::string("\nState: ") + zoneStateToString(vsm_zone_get_state(zone))
- + std::string("\nRoot: ") + vsm_zone_get_rootfs(zone);
- return out;
-}
-
std::string netdevTypeToString(const VsmNetdevType& netdevType)
{
std::string type;
throw runtime_error("Unsupported macvlan mode");
}
+void buildZoneList(std::vector<std::string>& list)
+{
+ using namespace std::placeholders;
+ VsmArrayString ids;
+
+ CommandLineInterface::executeCallback(bind(vsm_get_zone_ids, _1, &ids));
+ for (VsmString* id = ids; *id; ++id) {
+ list.push_back(*id);
+ }
+ vsm_array_string_free(ids);
+}
+
} // namespace
+const std::vector<std::string> CommandLineInterface::buildCompletionList(const Args& a) const
+{
+ std::vector<std::string> v;
+
+ if (a.size() > mArgsSpec.size() + 1) {
+ return v;
+ }
+
+ ArgSpec as = mArgsSpec[a.size() - 2];
+ string::size_type s = 0U;
+ string::size_type e = s;
+ while (e != string::npos) {
+ e = as.format.find('|', s);
+ std::string ss = as.format.substr(s, e - s);
+ s = e + 1;
+
+ if (ss == "{ZONE}") {
+ buildZoneList(v);
+ }
+ else if (ss == "{NETDEV}") {
+ //TODO: get list of available interfaces
+ v.push_back("lo");
+ v.push_back("eth0");
+ }
+ else if (ss.length() > 0) {
+ v.push_back(ss);
+ }
+ }
+
+ return v;
+}
+
void CommandLineInterface::connect()
{
VsmStatus status;
+ if (CommandLineInterface::client != nullptr) {
+ return;
+ }
CommandLineInterface::client = vsm_client_create();
- if (NULL == CommandLineInterface::client) {
+ if (CommandLineInterface::client == nullptr) {
throw runtime_error("Can't create client");
}
if (VSMCLIENT_SUCCESS != status) {
string msg = vsm_get_status_message(CommandLineInterface::client);
vsm_client_free(CommandLineInterface::client);
- CommandLineInterface::client = NULL;
+ CommandLineInterface::client = nullptr;
throw runtime_error(msg);
}
}
string msg;
VsmStatus status;
+ if (CommandLineInterface::client == nullptr) {
+ return ;
+ }
+
status = vsm_disconnect(CommandLineInterface::client);
if (VSMCLIENT_SUCCESS != status) {
msg = vsm_get_status_message(CommandLineInterface::client);
}
vsm_client_free(CommandLineInterface::client);
- CommandLineInterface::client = NULL;
+ CommandLineInterface::client = nullptr;
if (VSMCLIENT_SUCCESS != status) {
throw runtime_error(msg);
void CommandLineInterface::executeCallback(const function<VsmStatus(VsmClient)>& fun)
{
- VsmStatus status;
+ CommandLineInterface::connect();
- status = fun(CommandLineInterface::client);
+ VsmStatus status = fun(CommandLineInterface::client);
if (VSMCLIENT_SUCCESS != status) {
throw runtime_error(vsm_get_status_message(CommandLineInterface::client));
}
{
out << mName;
for (const auto& args : mArgsSpec) {
- out << " " << args.first;
+ out << " " << args.name;
}
out << "\n\n"
if (!mArgsSpec.empty()) {
out << "\n\tOptions\n";
for (const auto& args : mArgsSpec) {
- out << "\t\t" << args.first << " -- " << args.second << "\n";
+ out << "\t\t" << args.name << " -- " << args.description << "\n";
}
}
out << "\n";
return (mAvailability & mode) == mode;
}
-void CommandLineInterface::execute(const Args& argv)
+void CommandLineInterface::execute(const Args& argv) const
{
mExecutorCallback(argv);
}
{
using namespace std::placeholders;
- if (argv.size() <= 1) {
+ if (argv.size() < 2) {
throw runtime_error("Not enough parameters");
}
{
using namespace std::placeholders;
- if (argv.size() <= 1) {
+ if (argv.size() < 2) {
throw runtime_error("Not enough parameters");
}
{
using namespace std::placeholders;
- if (argv.size() <= 1) {
+ if (argv.size() < 2) {
throw runtime_error("Not enough parameters");
}
{
using namespace std::placeholders;
- if (argv.size() <= 1) {
+ if (argv.size() < 2) {
throw runtime_error("Not enough parameters");
}
{
using namespace std::placeholders;
- if (argv.size() <= 1) {
+ if (argv.size() < 2) {
throw runtime_error("Not enough parameters");
}
{
using namespace std::placeholders;
- if (argv.size() <= 1) {
+ if (argv.size() < 2) {
throw runtime_error("Not enough parameters");
}
if (zoneStateToString(vsm_zone_get_state(zone)) != "RUNNING") {
vsm_zone_free(zone);
- throw runtime_error("Zone is not running");
+ throw runtime_error("Zone '" + argv[1] + "' is not running");
}
std::string zonesPath = vsm_zone_get_rootfs(zone);
{
using namespace std::placeholders;
- if (argv.size() <= 1) {
+ if (argv.size() < 2) {
throw runtime_error("Not enough parameters");
}
{
using namespace std::placeholders;
- if (argv.size() <= 1) {
+ if (argv.size() < 2) {
throw runtime_error("Not enough parameters");
}
CommandLineInterface::executeCallback(bind(vsm_unlock_zone, _1, argv[1].c_str()));
}
-void get_zones_status(const Args& /* argv */)
+void get_zones_status(const Args& argv)
{
using namespace std::placeholders;
VsmString activeId;
Table table;
- CommandLineInterface::executeCallback(bind(vsm_get_zone_ids, _1, &ids));
+ if (argv.size() < 2) {
+ CommandLineInterface::executeCallback(bind(vsm_get_zone_ids, _1, &ids));
+ }
+ else {
+ ids = reinterpret_cast<char**>(calloc(argv.size(), sizeof(char*)));
+ for (unsigned i = 1; i<argv.size(); ++i) {
+ ids[i - 1] = ::strdup(argv[i].c_str());
+ }
+ }
+
+
CommandLineInterface::executeCallback(bind(vsm_get_active_zone_id, _1, &activeId));
table.push_back({"Active", "Id", "State", "Terminal", "Root"});
for (VsmString* id = ids; *id; ++id) {
VsmZone zone;
CommandLineInterface::executeCallback(bind(vsm_lookup_zone_by_id, _1, *id, &zone));
assert(string(vsm_zone_get_id(zone)) == string(*id));
- table.push_back({string(vsm_zone_get_id(zone)) == string(activeId) ? "*" : "",
+ table.push_back({string(vsm_zone_get_id(zone)) == string(activeId) ? "YES" : "NO",
vsm_zone_get_id(zone),
zoneStateToString(vsm_zone_get_state(zone)),
to_string(vsm_zone_get_terminal(zone)),
vsm_array_string_free(ids);
}
-void get_active_zone_id(const Args& /*argv*/)
+void get_active_zone(const Args& /*argv*/)
{
using namespace std::placeholders;
vsm_string_free(id);
}
-void lookup_zone_by_id(const Args& argv)
-{
- using namespace std::placeholders;
- if (argv.size() <= 1) {
- throw runtime_error("Not enough parameters");
- }
-
- VsmZone zone;
- CommandLineInterface::executeCallback(bind(vsm_lookup_zone_by_id, _1, argv[1].c_str(), &zone));
- cout << zoneToString(zone) << endl;
- vsm_zone_free(zone);
-}
-
void grant_device(const Args& argv)
{
using namespace std::placeholders;
- if (argv.size() <= 2) {
+ if (argv.size() < 3) {
throw runtime_error("Not enough parameters");
}
{
using namespace std::placeholders;
- if (argv.size() <= 2) {
+ if (argv.size() < 3) {
throw runtime_error("Not enough parameters");
}
CommandLineInterface::executeCallback(bind(vsm_revoke_device, _1, argv[1].c_str(), argv[2].c_str()));
}
-void create_netdev_veth(const Args& argv)
+void create_netdev(const Args& argv)
{
using namespace std::placeholders;
- if (argv.size() <= 3) {
+ if (argv.size() < 2) {
throw runtime_error("Not enough parameters");
}
- CommandLineInterface::executeCallback(bind(vsm_create_netdev_veth,
+
+ std::string nettype = argv[2];
+ if (nettype == "phys") {
+ if (argv.size() < 4) {
+ throw runtime_error("Not enough parameters");
+ }
+ CommandLineInterface::executeCallback(bind(vsm_create_netdev_phys,
_1,
argv[1].c_str(),
- argv[2].c_str(),
argv[3].c_str()));
-}
-
-void create_netdev_macvlan(const Args& argv)
-{
- using namespace std::placeholders;
-
- if (argv.size() <= 4) {
- throw runtime_error("Not enough parameters");
}
- CommandLineInterface::executeCallback(bind(vsm_create_netdev_macvlan,
+ else if (nettype == "veth") {
+ if (argv.size() < 5) {
+ throw runtime_error("Not enough parameters");
+ }
+ CommandLineInterface::executeCallback(bind(vsm_create_netdev_veth,
_1,
argv[1].c_str(),
- argv[2].c_str(),
argv[3].c_str(),
- macvlanFromString(argv[4].c_str())));
-}
-
-void create_netdev_phys(const Args& argv)
-{
- using namespace std::placeholders;
-
- if (argv.size() <= 2) {
- throw runtime_error("Not enough parameters");
+ argv[4].c_str()));
}
- CommandLineInterface::executeCallback(bind(vsm_create_netdev_phys,
+ else if (nettype == "macvlan") {
+ if (argv.size() < 6) {
+ throw runtime_error("Not enough parameters");
+ }
+ CommandLineInterface::executeCallback(bind(vsm_create_netdev_macvlan,
_1,
argv[1].c_str(),
- argv[2].c_str()));
-}
-
-void lookup_netdev_by_name(const Args& argv)
-{
- using namespace std::placeholders;
-
- if (argv.size() <= 2) {
- throw runtime_error("Not enough parameters");
+ argv[3].c_str(),
+ argv[4].c_str(),
+ macvlanFromString(argv[5].c_str())));
}
- VsmNetdev netdev = NULL;
- CommandLineInterface::executeCallback(bind(vsm_lookup_netdev_by_name,
- _1,
- argv[1].c_str(),
- argv[2].c_str(),
- &netdev));
- cout << netdevToString(netdev) << endl;
- vsm_netdev_free(netdev);
-
+ else
+ throw runtime_error("Wrong nettype option " + nettype);
}
void destroy_netdev(const Args& argv)
{
using namespace std::placeholders;
- if (argv.size() <= 2) {
+ if (argv.size() < 3) {
throw runtime_error("Not enough parameters");
}
CommandLineInterface::executeCallback(bind(vsm_destroy_netdev,
argv[2].c_str()));
}
-void zone_get_netdevs(const Args& argv)
+void netdev_list(const Args& argv)
{
using namespace std::placeholders;
- if (argv.size() <= 1) {
+ if (argv.size() < 2) {
throw runtime_error("Not enough parameters");
}
- VsmArrayString ids;
- CommandLineInterface::executeCallback(bind(vsm_zone_get_netdevs,
+ if (argv.size() < 3) {
+ VsmArrayString ids;
+ CommandLineInterface::executeCallback(bind(vsm_zone_get_netdevs,
_1,
argv[1].c_str(),
&ids));
- string delim;
- for (VsmString* id = ids; *id; ++id) {
- cout << delim << *id;
- delim = ", ";
- }
- if (delim.empty()) {
- cout << "There is no network device in zone";
- }
- cout << endl;
- vsm_array_string_free(ids);
-}
+ string delim;
+ for (VsmString* id = ids; *id; ++id) {
+ cout << delim << *id;
+ delim = ", ";
+ }
+ if (delim.empty()) {
+ cout << "There is no network device in zone";
+ }
+ cout << endl;
+ vsm_array_string_free(ids);
+ }
+ else {
+ VsmNetdev netdev = NULL;
+ in_addr ipv4;
+ in6_addr ipv6;
+ char buf[INET_ADDRSTRLEN|INET6_ADDRSTRLEN];
+ CommandLineInterface::executeCallback(bind(vsm_lookup_netdev_by_name,
+ _1,
+ argv[1].c_str(),
+ argv[2].c_str(),
+ &netdev));
+ cout << netdevToString(netdev) << endl;
+ vsm_netdev_free(netdev);
-void netdev_get_ipv4_addr(const Args& argv)
-{
- using namespace std::placeholders;
+ CommandLineInterface::executeCallback(bind(vsm_netdev_get_ipv4_addr,
+ _1,
+ argv[1].c_str(),
+ argv[2].c_str(),
+ &ipv4));
+ if (inet_ntop(AF_INET, &ipv4, buf, INET_ADDRSTRLEN) == NULL) {
+ throw runtime_error("Wrong address received");
+ }
+ cout << buf << endl;
- if (argv.size() <= 2) {
- throw runtime_error("Not enough parameters");
- }
- in_addr addr;
- CommandLineInterface::executeCallback(bind(vsm_netdev_get_ipv4_addr,
+ CommandLineInterface::executeCallback(bind(vsm_netdev_get_ipv6_addr,
_1,
argv[1].c_str(),
argv[2].c_str(),
- &addr));
- char buf[INET_ADDRSTRLEN];
- if (inet_ntop(AF_INET, &addr, buf, INET_ADDRSTRLEN) == NULL) {
- throw runtime_error("Server gave the wrong address format");
+ &ipv6));
+ if (inet_ntop(AF_INET6, &ipv6, buf, INET6_ADDRSTRLEN) == NULL) {
+ throw runtime_error("Wrong address received");
+ }
+ cout << buf << endl;
}
- cout << buf << endl;
}
-void netdev_get_ipv6_addr(const Args& argv)
+void netdev_add_ip_addr(const Args& argv)
{
using namespace std::placeholders;
-
- if (argv.size() <= 2) {
+ if (argv.size() < 5) {
throw runtime_error("Not enough parameters");
}
- in6_addr addr;
- CommandLineInterface::executeCallback(bind(vsm_netdev_get_ipv6_addr,
+ if (argv[3].find(':') == std::string::npos) {
+ in_addr addr;
+ if (inet_pton(AF_INET, argv[3].c_str(), &addr) != 1) {
+ throw runtime_error("Wrong address format");
+ };
+ CommandLineInterface::executeCallback(bind(vsm_netdev_set_ipv4_addr,
+ _1,
+ argv[1].c_str(),
+ argv[2].c_str(),
+ &addr,
+ stoi(argv[4].c_str())));
+ }
+ else {
+ in6_addr addr;
+ if (inet_pton(AF_INET6, argv[3].c_str(), &addr) != 1) {
+ throw runtime_error("Wrong address format");
+ };
+ CommandLineInterface::executeCallback(bind(vsm_netdev_set_ipv6_addr,
_1,
argv[1].c_str(),
argv[2].c_str(),
- &addr));
- char buf[INET6_ADDRSTRLEN];
- if (inet_ntop(AF_INET6, &addr, buf, INET6_ADDRSTRLEN) == NULL) {
- throw runtime_error("Server gave the wrong address format");
+ &addr,
+ stoi(argv[4].c_str())));
}
- cout << buf << endl;
}
-void netdev_set_ipv4_addr(const Args& argv)
+void netdev_del_ip_addr(const Args& argv)
{
using namespace std::placeholders;
-
- if (argv.size() <= 4) {
+ if (argv.size() < 5) {
throw runtime_error("Not enough parameters");
}
- in_addr addr;
- if (inet_pton(AF_INET, argv[3].c_str(), &addr) != 1) {
- throw runtime_error("Wrong address format");
- };
- CommandLineInterface::executeCallback(bind(vsm_netdev_set_ipv4_addr,
+ if (argv[3].find(':') == std::string::npos) {
+ in_addr addr;
+ if (inet_pton(AF_INET, argv[3].c_str(), &addr) != 1) {
+ throw runtime_error("Wrong address format");
+ };
+ CommandLineInterface::executeCallback(bind(vsm_netdev_del_ipv4_addr,
_1,
argv[1].c_str(),
argv[2].c_str(),
&addr,
stoi(argv[4].c_str())));
-}
-
-void netdev_set_ipv6_addr(const Args& argv)
-{
- using namespace std::placeholders;
-
- if (argv.size() <= 4) {
- throw runtime_error("Not enough parameters");
}
- in6_addr addr;
- if (inet_pton(AF_INET6, argv[3].c_str(), &addr) != 1) {
- throw runtime_error("Wrong address format");
- };
- CommandLineInterface::executeCallback(bind(vsm_netdev_set_ipv6_addr,
+ else {
+ in6_addr addr;
+ if (inet_pton(AF_INET6, argv[3].c_str(), &addr) != 1) {
+ throw runtime_error("Wrong address format");
+ };
+ CommandLineInterface::executeCallback(bind(vsm_netdev_del_ipv6_addr,
_1,
argv[1].c_str(),
argv[2].c_str(),
&addr,
stoi(argv[4].c_str())));
+ }
}
void netdev_up(const Args& argv)
{
using namespace std::placeholders;
- if (argv.size() <= 2) {
+ if (argv.size() < 3) {
throw runtime_error("Not enough parameters");
}
CommandLineInterface::executeCallback(bind(vsm_netdev_up,
{
using namespace std::placeholders;
- if (argv.size() <= 2) {
+ if (argv.size() < 3) {
throw runtime_error("Not enough parameters");
}
CommandLineInterface::executeCallback(bind(vsm_netdev_down,
typedef std::vector<std::string> Args;
+struct ArgSpec {
+ std::string name;
+ std::string description;
+ std::string format;
+};
+
/**
* Class that implements command pattern.
*/
/**
* @see CommandLineInterface::CommandLineInterface
*/
- typedef std::vector<std::pair<std::string, std::string>> ArgsSpec;
+ typedef std::vector<ArgSpec> ArgsSpec;
/**
* Dummy constructor (for stl usage)
*
* @param argv Command line arguments
*/
- void execute(const Args& argv);
+ void execute(const Args& argv) const;
+ const std::vector<std::string> buildCompletionList(const Args& argv) const;
private:
static VsmClient client;
*
* @see vsm_get_active_zone_id
*/
-void get_active_zone_id(const Args& argv);
-
-/**
- * Parses command line arguments and call vsm_lookup_zone_by_id
- *
- * @see vsm_lookup_zone_by_id
- */
-void lookup_zone_by_id(const Args& argv);
+void get_active_zone(const Args& argv);
/**
* Parses command line arguments and call vsm_grant_device
void revoke_device(const Args& argv);
/**
- * Parses command line arguments and call vsm_create_netdev_veth
- *
- * @see vsm_create_netdev_veth
- */
-void create_netdev_veth(const Args& argv);
-
-/**
- * Parses command line arguments and call vsm_create_netdev_macvlan
- *
- * @see vsm_create_netdev_macvlan
- */
-void create_netdev_macvlan(const Args& argv);
-
-/**
- * Parses command line arguments and call vsm_create_netdev_phys
+ * Parses command line arguments and call vsm_create_netdev_*
*
- * @see vsm_create_netdev_phys
+ * @see vsm_create_netdev_veth,vsm_create_netdev_macvlan,vsm_create_netdev_phys
*/
-void create_netdev_phys(const Args& argv);
-
-/**
- * Parses command line arguments and call vsm_lookup_netdev_by_name
- *
- * @see vsm_lookup_netdev_by_name
- */
-void lookup_netdev_by_name(const Args& argv);
+void create_netdev(const Args& argv);
/**
* Parses command line arguments and call vsm_destroy_netdev
void destroy_netdev(const Args& argv);
/**
- * Parses command line arguments and prints result of vsm_zone_get_netdevs
- *
- * @see vsm_zone_get_netdevs
- */
-void zone_get_netdevs(const Args& argv);
-
-/**
- * Parses command line arguments and prints result of vsm_netdev_get_ipv4_addr
- *
- * @see vsm_netdev_get_ipv4_addr
- */
-void netdev_get_ipv4_addr(const Args& argv);
-
-/**
- * Parses command line arguments and and prints result of vsm_netdev_get_ipv6_addr
+ * Parses command line arguments and prints result of vsm_zone_get_netdevs,
+ * vsm_lookup_netdev_by_name, vsm_netdev_get_ipv4_addr, vsm_netdev_get_ipv6_addr
*
- * @see vsm_netdev_get_ipv6_addr
+ * @see vsm_zone_get_netdevs, vsm_lookup_netdev_by_name,
+ * @see vsm_netdev_get_ipv4_addr, vsm_netdev_get_ipv6_addr
*/
-void netdev_get_ipv6_addr(const Args& argv);
+void netdev_list(const Args& argv);
/**
- * Parses command line arguments and call vsm_netdev_set_ipv4_addr
+ * Parses command line arguments and call vsm_netdev_set_ipv4_addr, vsm_netdev_set_ipv6_addr
*
- * @see vsm_netdev_set_ipv4_addr
+ * @see vsm_netdev_set_ipv4_addr, vsm_netdev_set_ipv6_addr
*/
-void netdev_set_ipv4_addr(const Args& argv);
+void netdev_add_ip_addr(const Args& argv);
/**
- * Parses command line arguments and call vsm_netdev_set_ipv6_addr
+ * Parses command line arguments and call vsm_netdev_del_ipv4_addr, vsm_netdev_del_ipv6_addr
*
- * @see vsm_netdev_set_ipv6_addr
+ * @see vsm_netdev_del_ipv4_addr, vsm_netdev_del_ipv6_addr
*/
-void netdev_set_ipv6_addr(const Args& argv);
+void netdev_del_ip_addr(const Args& argv);
/**
* Parses command line arguments and call vsm_netdev_up
namespace {
static int interactiveMode = 0;
-std::map<std::string, CommandLineInterface> commands = {
+std::vector<CommandLineInterface> commands = {
{
- "lock_queue", {
- lock_queue,
- "lock_queue",
- "Exclusively lock the command queue",
- MODE_INTERACTIVE,
- {}
- }
- },
- {
- "unlock_queue", {
- unlock_queue,
- "unlock_queue",
- "Unlock the queue",
- MODE_INTERACTIVE,
- {}
- }
- },
- {
- "set_active_zone", {
- set_active_zone,
- "set_active_zone",
- "Set active (foreground) zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"}}
- }
- },
- {
- "create_zone", {
- create_zone,
- "create_zone",
- "Create and add zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"[zone_tname]", "optional zone template name"}}
- }
- },
- {
- "destroy_zone", {
- destroy_zone,
- "destroy_zone",
- "Destroy zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"}}
- }
- },
- {
- "shutdown_zone", {
- shutdown_zone,
- "shutdown_zone",
- "Shutdown zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"}}
- }
+ create_zone,
+ "create",
+ "Create and add zone",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", ""},
+ {"[zone_tname]", "optional zone template name", ""}}
},
{
- "start_zone", {
- start_zone,
- "start_zone",
- "Start zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"}}
- }
+ destroy_zone,
+ "destroy",
+ "Destroy zone",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"}}
},
{
- "console_zone", {
- console_zone,
- "console_zone",
- "Log into zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"}}
- }
- },
- {
- "lock_zone", {
- lock_zone,
- "lock_zone",
- "Lock zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"}}
- }
+ start_zone,
+ "start",
+ "Start zone",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"}}
},
{
- "unlock_zone", {
- unlock_zone,
- "unlock_zone",
- "Unlock zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"}}
- }
+ console_zone,
+ "console",
+ "Attach to zone text console",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"}}
},
{
- "get_zones_status", {
- get_zones_status,
- "get_zones_status",
- "Get list of zone with some useful informations (id, state, terminal, root path)",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {}
- }
+ shutdown_zone,
+ "shutdown",
+ "Shutdown zone",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"}}
},
{
- "get_zone_ids", {
- get_zone_ids,
- "get_zone_ids",
- "Get all zone ids",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {}
- }
+ lock_zone,
+ "suspend",
+ "Suspend (lock) zone",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"}}
},
{
- "get_active_zone_id", {
- get_active_zone_id,
- "get_active_zone_id",
- "Get active (foreground) zone ids",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {}
- }
+ unlock_zone,
+ "resume",
+ "Resume (unlock) zone",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"}}
},
{
- "lookup_zone_by_id", {
- lookup_zone_by_id,
- "lookup_zone_by_id",
- "Prints informations about zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"}}
- }
+ set_active_zone,
+ "set-active",
+ "Set active (foreground) zone",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"}}
},
{
- "grant_device", {
- grant_device,
- "grant_device",
- "Grants access to the given device",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"device_name", " device name"}}
- }
+ get_active_zone,
+ "get-active",
+ "Get active (foreground) zone",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {}
},
{
- "revoke_device", {
- revoke_device,
- "revoke_device",
- "Revokes access to the given device",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"device_name", " device name"}}
- }
+ get_zone_ids,
+ "list",
+ "Get available zone ids",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {}
},
{
- "create_netdev_veth", {
- create_netdev_veth,
- "create_netdev_veth",
- "Create netdev in zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"zone_netdev_id", "network device id"},
- {"host_netdev_id", "host bridge id"}}
- }
+ get_zones_status,
+ "status",
+ "List status for one or all zones (id, state, terminal, root path)",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"[zone_id]", "zone name", "{ZONE}"}}
},
{
- "create_netdev_macvlan", {
- create_netdev_macvlan,
- "create_netdev_macvlan",
- "Create netdev in zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"zone_netdev_id", "network device id"},
- {"host_netdev_id", "host bridge id"},
- {"mode", "macvlan mode (private, vepa, bridge, passthru)"}}
- }
+ clean_up_zones_root,
+ "clean",
+ "Clean up zones root directory",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {}
},
{
- "create_netdev_phys", {
- create_netdev_phys,
- "create_netdev_phys",
- "Create/move netdev to zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"netdev_id", "network device name"}}
- }
+ grant_device,
+ "device-grant",
+ "Grants access to the given device",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"},
+ {"device", "device name", ""}}
},
{
- "lookup_netdev_by_name", {
- lookup_netdev_by_name,
- "lookup_netdev_by_name",
- "Get netdev flags",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"netdev_id", "network device name"}}
- }
+ revoke_device,
+ "device-revoke",
+ "Revokes access to the given device",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"},
+ {"device", "device name", ""}}
},
{
- "destroy_netdev", {
- destroy_netdev,
- "destroy_netdev",
- "Destroy netdev in zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"netdev_id", "network device name"}}
- }
+ create_netdev,
+ "net-create",
+ "Create network interface in zone",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {
+ {"zone_id", "zone name", "{ZONE}"},
+ {"netdevtype", "interface type", "macvlan|phys|veth"},
+ {"zone_netdev", "interface name (eth0)", "eth0|eth1"},
+ {"host_netdev", "bridge name (virbr0)", "virbr0|virbr1"},
+ {"mode", "macvlan mode (private, vepa, bridge, passthru)", "private|vepa|bridge|passthru"}}
},
{
- "zone_get_netdevs", {
- zone_get_netdevs,
- "zone_get_netdevs",
- "List network devices in the zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"}}
- }
+ destroy_netdev,
+ "net-destroy",
+ "Destroy netdev in zone",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"},
+ {"netdev", "interface name (eth0)", "{NETDEV}"}}
},
{
- "netdev_get_ipv4_addr", {
- netdev_get_ipv4_addr,
- "netdev_get_ipv4_addr",
- "Get ipv4 address",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"netdev_id", "network device name"}}
- }
+ netdev_list,
+ "net-list",
+ "List network devices in the zone",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"},
+ {"[netdev]", "interface name (eth0)", "{NETDEV}"}}
},
{
- "netdev_get_ipv6_addr", {
- netdev_get_ipv6_addr,
- "netdev_get_ipv6_addr",
- "Get ipv6 address",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"netdev_id", "network device name"}}
- }
+ netdev_up,
+ "net-up",
+ "Setup a network device in the zone up",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"},
+ {"netdev", "interface name (eth0)", "{NETDEV}"}}
},
{
- "netdev_set_ipv4_addr", {
- netdev_set_ipv4_addr,
- "netdev_set_ipv4_addr",
- "Set ipv4 address",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"netdev_id", "network device name"},
- {"address", "ipv4 address"},
- {"prefix_len", "bit length of prefix"}}
- }
+ netdev_down,
+ "net-down",
+ "Setup a network device in the zone down",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"},
+ {"netdev", "interface name (eth0)", "{NETDEV}"}}
},
{
- "netdev_set_ipv6_addr", {
- netdev_set_ipv6_addr,
- "netdev_set_ipv6_addr",
- "Set ipv6 address",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"netdev_id", "network device name"},
- {"address", "ipv6 address"},
- {"prefix_len", "bit length of prefix"}}
- }
+ netdev_add_ip_addr,
+ "net-ip-add",
+ "Add ip/mask address to network interface",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"},
+ {"netdev", "interface name (eth0)", "{NETDEV}"},
+ {"ip", "address IPv4 or IPv6", ""},
+ {"prefix", "mask length in bits", "24"}}
},
{
- "netdev_up", {
- netdev_up,
- "netdev_up",
- "Turn up a network device in the zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"netdev_id", "network device id"}}
- }
+ netdev_del_ip_addr,
+ "net-ip-del",
+ "Del ip/mask address from network interface",
+ MODE_COMMAND_LINE | MODE_INTERACTIVE,
+ {{"zone_id", "zone name", "{ZONE}"},
+ {"netdev", "interface name (eth0)", "{NETDEV}"},
+ {"ip", "address IPv4 or IPv6", ""},
+ {"prefix", "mask length in bits", "24"}}
},
{
- "netdev_down", {
- netdev_down,
- "netdev_down",
- "Turn down a network device in the zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"netdev_id", "network device id"}}
- }
+ lock_queue,
+ "qlock",
+ "Exclusively lock the command queue",
+ MODE_INTERACTIVE,
+ {}
},
{
- "zone_get_netdevs", {
- zone_get_netdevs,
- "zone_get_netdevs",
- "Turn down a network device in the zone",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {{"zone_id", "id zone name"},
- {"netdev_id", "network device id"}}
- }
+ unlock_queue,
+ "qunlock",
+ "Unlock the queue",
+ MODE_INTERACTIVE,
+ {}
},
- {
- "clean_up_zones_root", {
- clean_up_zones_root,
- "clean_up_zones_root",
- "Clean up zones root directory",
- MODE_COMMAND_LINE | MODE_INTERACTIVE,
- {}
- }
- }
};
+std::map<std::string,const CommandLineInterface> commandMap;
+
// wrappers for CommandLineInterface
void printUsage(std::ostream& out, const std::string& name, unsigned int mode)
{
+ const std::vector<std::string> addLineBefore = {"device-grant", "net-create", "qlock"};
std::string n;
if (!name.empty()) {
n = name + " ";
out << "command can be one of the following:\n";
for (const auto& command : commands) {
- if (command.second.isAvailable(mode)) {
- out << " " << std::setw(30) << std::left << command.second.getName()
- << command.second.getDescription() << "\n";
+ if (command.isAvailable(mode)) {
+ if (std::find(addLineBefore.begin(), addLineBefore.end(), command.getName()) != addLineBefore.end()) {
+ out << std::endl;
+ }
+ out << " " << std::setw(25) << std::left << command.getName()
+ << command.getDescription() << std::endl;
}
}
int executeCommand(const Args& argv, int mode)
{
- auto pair = commands.find(argv[0]);
- if (pair == commands.end()) {
+ auto pair = commandMap.find(argv[0]);
+ if (pair == commandMap.end()) {
return EXIT_FAILURE;
}
- CommandLineInterface& command = pair->second;
+ const CommandLineInterface& command = pair->second;
if (!command.isAvailable(mode)) {
+ std::cerr << "Command not available in this mode" << std::endl;
return EXIT_FAILURE;
}
}
// readline completion support
-
-char* object_generator(const char* text, int state)
+const std::vector<std::string> buildComplList(const Args& argv);
+char *completion_generator(const char* text, int state)
{
- static std::vector<std::string> objs;
- static size_t len = 0, index = 0;
-
+ static std::vector<std::string> list;
+ static unsigned index = 0;
if (state == 0) {
- objs.clear();
- len = ::strlen(text);
+ list.clear();
index = 0;
- using namespace std::placeholders;
- VsmArrayString ids = NULL;
- try {
- CommandLineInterface::executeCallback(bind(vsm_get_zone_ids, _1, &ids));
- } catch (const std::runtime_error& ex) {
- // Quietly ignore, nothing we can do anyway
- }
-
- if (ids != NULL) {
- for (VsmString* id = ids; *id; ++id) {
- if (::strncmp(text, *id, len) == 0) {
- objs.push_back(*id);
- }
- }
+ char *ln = rl_line_buffer;
+ std::istringstream iss(ln);
+ Args argv{std::istream_iterator<std::string>{iss},
+ std::istream_iterator<std::string>{}};
- vsm_array_string_free(ids);
+ size_t len = strlen(text);
+ if (len == 0 && argv.size() > 0) {
+ argv.push_back("");
}
- }
- if (index < objs.size()) {
- return ::strdup(objs[index++].c_str());
- }
-
- return NULL;
-}
-
-char* cmd_generator(const char* text, int state)
-{
- static std::vector<std::string> cmds;
- static size_t len = 0, index = 0;
-
- if (state == 0) {
- cmds.clear();
- len = ::strlen(text);
- index = 0;
-
- for (const auto& command : commands) {
- if (command.second.isAvailable(MODE_INTERACTIVE)) {
- const std::string& cmd = command.second.getName();
- if (::strncmp(text, cmd.c_str(), len) == 0) {
- cmds.push_back(cmd);
- }
+ const std::vector<std::string>& l = buildComplList(argv);
+ for (const auto &i : l) {
+ if (strncmp(text, i.c_str(), len) == 0) {
+ list.push_back(i);
}
}
}
-
- if (index < cmds.size()) {
- return ::strdup(cmds[index++].c_str());
+ if (index < list.size()) {
+ return ::strdup(list[index++].c_str());
}
return NULL;
}
-char** completion(const char* text, int start, int /*end*/)
+char** completion(const char* text, int /*start*/, int /*end*/)
{
- char **matches = NULL;
-
- if (start == 0) {
- matches = ::rl_completion_matches(text, &cmd_generator);
- } else {
- matches = ::rl_completion_matches(text, &object_generator);
- }
-
- return matches;
+ ::rl_attempted_completion_over = 1; //disable default completion
+ return ::rl_completion_matches(text, &completion_generator);
}
static bool readline_from(const std::string& prompt, std::istream& stream, std::string& ln)
return EXIT_FAILURE;
}
+ int rc = EXIT_FAILURE;
std::string ln;
while (readline_from(">>> ", stream, ln)) {
if (ln.empty() || ln[0] == '#') { //skip empty line or comment
Args argv{std::istream_iterator<std::string>{iss},
std::istream_iterator<std::string>{}};
- if (commands.count(argv[0]) == 0) {
+ if (commandMap.count(argv[0]) == 0) {
printUsage(std::cout, "", MODE_INTERACTIVE);
continue;
}
- executeCommand(argv, MODE_INTERACTIVE);
+ rc = executeCommand(argv, MODE_INTERACTIVE);
+ if (rc == EXIT_FAILURE && !interactiveMode) {
+ break;
+ }
}
- disconnect();
- return EXIT_SUCCESS;
+ return rc;
}
static int processFile(const std::string& fn)
return processStream(stream);
}
-int bashComplMode()
+void printList(const std::vector<std::string>& list)
{
- for (const auto& command : commands) {
- if (command.second.isAvailable(MODE_COMMAND_LINE)) {
- std::cout << command.second.getName() << "\n";
+ for (const auto& i : list) {
+ std::cout << i << std::endl;
+ }
+}
+
+const std::vector<std::string> buildComplList(const Args& argv)
+{
+ if (argv.size() < 2) {
+ std::vector<std::string> list;
+ for (const auto& command : commands) {
+ if (command.isAvailable(MODE_COMMAND_LINE)) {
+ list.push_back(command.getName());
+ }
+ }
+ return list;
+ } else {
+ std::string cmd = argv[0];
+ if (commandMap.find(cmd) != commandMap.end()) {
+ return commandMap[cmd].buildCompletionList(argv);
}
+ return std::vector<std::string>();
}
+}
- return EXIT_SUCCESS;
+int bashComplMode(int argc, const char *argv[])
+{
+ int rc = EXIT_FAILURE;
+ try {
+ Args args(argv, argv + argc);
+ printList(buildComplList(args));
+ rc = EXIT_SUCCESS;
+ } catch (const std::runtime_error& ex) {
+ }
+
+ return rc;
}
int cliMode(const int argc, const char** argv)
return EXIT_SUCCESS;
}
- if (commands.find(argv[1]) == commands.end()) {
+ if (commandMap.find(argv[1]) == commandMap.end()) {
printUsage(std::cout, argv[0], MODE_COMMAND_LINE);
return EXIT_FAILURE;
}
- //TODO: Connect when it is necessary
- //f.e. vasum-cli <command> -h doesn't need connection
- if (connect() != EXIT_SUCCESS) {
- return EXIT_FAILURE;
- }
-
// pass all the arguments excluding argv[0] - the executable name
- Args commandArgs(argv+1, argv+argc);
+ Args commandArgs(argv + 1, argv + argc);
int rc = executeCommand(commandArgs, MODE_COMMAND_LINE);
- disconnect();
return rc;
}
int main(const int argc, const char *argv[])
{
+ for (const auto& command : commands) {
+ commandMap.insert(std::pair<std::string,const CommandLineInterface>(command.getName(),command));
+ }
+
+ int rc = EXIT_FAILURE;
if (argc > 1) {
+
//process arguments
if (std::string(argv[1]) == "--bash-completion") {
- return bashComplMode();
- }
-
- if (std::string(argv[1]) == "-f") {
+ rc = bashComplMode(argc - 2, argv + 2);
+ } else if (std::string(argv[1]) == "-f") {
if (argc < 3) {
std::cerr << "Filename expected" << std::endl;
- return EXIT_FAILURE;
+ rc = EXIT_FAILURE;
+ }
+ else {
+ rc = processFile(std::string(argv[2]));
}
- return processFile(std::string(argv[2]));
+ } else {
+ rc = cliMode(argc, argv);
}
- return cliMode(argc, argv);
- }
+ } else {
+
+ if (isatty(0) == 1) {
+ interactiveMode = 1;
+ ::rl_attempted_completion_function = completion;
+ }
- if (isatty(0) == 1) {
- interactiveMode = 1;
- ::rl_attempted_completion_function = completion;
+ rc = processStream(std::cin);
}
- return processStream(std::cin);
+
+ disconnect();
+ return rc;
}
+++ /dev/null
-# Check for bash
-[ -z "$BASH_VERSION" ] && return
-
-__@PROJECT_NAME@_cli() {
- local cur="${COMP_WORDS[COMP_CWORD]}"
-
- COMPREPLY=()
- if [ "$COMP_CWORD" == "1" ]; then
- COMPREPLY=($(compgen -W "$(@CLI_CODENAME@ --bash-completion)" -- $cur))
- elif [ "$COMP_CWORD" == "2" ]; then
- COMPREPLY=($(compgen -W "-h" -- $cur))
- fi
-}
-
-complete -F __@PROJECT_NAME@_cli @CLI_CODENAME@
--- /dev/null
+# Check for bash
+[ -z "$BASH_VERSION" ] && return
+
+__@PROJECT_NAME@_cli() {
+ local exe=$1 cur=$2 prev=$3
+ words=`@CLI_CODENAME@ --bash-completion "${COMP_WORDS[@]:1}"`
+ COMPREPLY=($(compgen -W "$words" -- $cur))
+}
+
+complete -F __@PROJECT_NAME@_cli vsm
mFd = utils::passNamespacedFd(netNsPid, CLONE_NEWNET, fdFactory);
}
if (mFd == -1) {
- throw VasumException("Can't open netlink connection");
+ throw VasumException("Can't open netlink connection (zone not running)");
}
sockaddr_nl local = utils::make_clean<sockaddr_nl>();
// It is NACK/ACK message
nlmsgerr *err = reinterpret_cast<nlmsgerr*>(NLMSG_DATA(answer));
if (answer->nlmsg_seq != nlmsgSeq) {
- throw VasumException("Sending failed: answer message was mismatched");
+ throw VasumException("Receive failed: answer message was mismatched");
}
if (err->error) {
- throw VasumException("Sending failed: " + getSystemErrorMessage(-err->error));
+ throw VasumException("Receive failed: " + getSystemErrorMessage(-err->error));
}
} else if (answer->nlmsg_type == NLMSG_OVERRUN) {
- throw VasumException("Sending failed: data lost");
+ throw VasumException("Receive failed: data lost");
}
}
if (lastOk == NULL) {
%files cli
%defattr(644,root,root,755)
-%attr(755,root,root) %{_bindir}/vasum-cli
+%attr(755,root,root) %{_bindir}/vsm
%package cli-completion
Summary: Vasum Command Line Interface bash completion
Command Line Interface bash completion for vasum.
%files cli-completion
-%attr(755,root,root) %{_sysconfdir}/bash_completion.d/vasum-cli-completion.sh
+%attr(755,root,root) %{_sysconfdir}/bash_completion.d/vsm-completion.sh
## Test Package ################################################################
%package tests
infoPeer.ifi_change = 0xFFFFFFFF;
nlm.put(infoPeer)
.put(IFLA_IFNAME, netdev);
- NetlinkResponse response = send(nlm, nsPid);
- if (!response.hasMessage()) {
- throw VasumException("Can't get interface information");
- }
- response.fetch(infoPeer);
-
Attrs attrs;
- while (response.hasAttribute()) {
- uint32_t mtu, link;
- int attrType = response.getAttributeType();
- switch (attrType) {
- case IFLA_MTU:
- response.fetch(IFLA_MTU, mtu);
- attrs.push_back(make_tuple("mtu", std::to_string(mtu)));
- break;
- case IFLA_LINK:
- response.fetch(IFLA_LINK, link);
- attrs.push_back(make_tuple("link", std::to_string(link)));
- break;
- default:
- response.skipAttribute();
- break;
+ try {
+ NetlinkResponse response = send(nlm, nsPid);
+ if (!response.hasMessage()) {
+ throw VasumException("Can't get interface information");
}
+ response.fetch(infoPeer);
+
+ while (response.hasAttribute()) {
+ uint32_t mtu, link;
+ int attrType = response.getAttributeType();
+ switch (attrType) {
+ case IFLA_MTU:
+ response.fetch(IFLA_MTU, mtu);
+ attrs.push_back(make_tuple("mtu", std::to_string(mtu)));
+ break;
+ case IFLA_LINK:
+ response.fetch(IFLA_LINK, link);
+ attrs.push_back(make_tuple("link", std::to_string(link)));
+ break;
+ default:
+ response.skipAttribute();
+ break;
+ }
+ }
+ } catch (const std::exception& ex) {
+ LOGE(ex.what());
+ throw VasumException(netdev + ": " + ex.what());
}
+
attrs.push_back(make_tuple("flags", std::to_string(infoPeer.ifi_flags)));
attrs.push_back(make_tuple("type", std::to_string(infoPeer.ifi_type)));
for (const auto& address : getIpAddresses(nsPid, AF_INET, infoPeer.ifi_index)) {
attrs.push_back(make_tuple("ipv4", joinAddresses(address)));
}
+
for (const auto& address : getIpAddresses(nsPid, AF_INET6, infoPeer.ifi_index)) {
attrs.push_back(make_tuple("ipv6", joinAddresses(address)));
}