ifquery: add --dot to visualize a calculated solution

This commit is contained in:
Ariadne Conill 2020-07-24 04:25:06 -06:00
parent 5c75cdcab0
commit 8138ca8485

View file

@ -61,6 +61,37 @@ print_interface(struct lif_interface *iface)
printf("\n");
}
void
print_interface_dot(struct lif_dict *collection, struct lif_interface *iface, struct lif_interface *parent)
{
if (iface->is_up)
return;
if (parent != NULL)
printf("\"%s\" -> ", parent->ifname);
printf("\"%s\"", iface->ifname);
printf("\n");
struct lif_dict_entry *entry = lif_dict_find(&iface->vars, "requires");
if (entry == NULL)
return;
char require_ifs[4096] = {};
strlcpy(require_ifs, entry->data, sizeof require_ifs);
char *reqp = require_ifs;
for (char *tokenp = lif_next_token(&reqp); *tokenp; tokenp = lif_next_token(&reqp))
{
struct lif_interface *child_if = lif_interface_collection_find(collection, tokenp);
print_interface_dot(collection, child_if, iface);
child_if->is_up = true;
}
}
void
ifquery_usage(void)
{
@ -78,6 +109,7 @@ ifquery_usage(void)
fprintf(stderr, " -P, --pretty-print pretty print the interfaces instead of just listing\n");
fprintf(stderr, " -S, --state-file FILE use FILE for state\n");
fprintf(stderr, " -s, --state show configured state\n");
fprintf(stderr, " -D, --dot generate a dependency graph\n");
exit(1);
}
@ -87,6 +119,7 @@ struct match_options {
char *exclude_pattern;
char *include_pattern;
bool pretty_print;
bool dot;
};
void
@ -94,6 +127,13 @@ list_interfaces(struct lif_dict *collection, struct match_options *opts)
{
struct lif_node *iter;
if (opts->dot)
{
printf("digraph interfaces {\n");
printf("edge [color=blue fontname=Sans fontsize=10]\n");
printf("node [fontname=Sans fontsize=10]\n");
}
LIF_DICT_FOREACH(iter, collection)
{
struct lif_dict_entry *entry = iter->data;
@ -112,9 +152,14 @@ list_interfaces(struct lif_dict *collection, struct match_options *opts)
if (opts->pretty_print)
print_interface(iface);
else if (opts->dot)
print_interface_dot(collection, iface, NULL);
else
printf("%s\n", iface->ifname);
}
if (opts->dot)
printf("}\n");
}
void
@ -154,6 +199,7 @@ ifquery_main(int argc, char *argv[])
{"pretty-print", no_argument, 0, 'P'},
{"state-file", required_argument, 0, 'S'},
{"state", no_argument, 0, 's'},
{"dot", no_argument, 0, 'D'},
{NULL, 0, 0, 0}
};
struct match_options match_opts = {};
@ -163,7 +209,7 @@ ifquery_main(int argc, char *argv[])
for (;;)
{
int c = getopt_long(argc, argv, "hVi:LaI:X:PS:s", long_options, NULL);
int c = getopt_long(argc, argv, "hVi:LaI:X:PS:sD", long_options, NULL);
if (c == -1)
break;
@ -198,6 +244,9 @@ ifquery_main(int argc, char *argv[])
case 's':
listing_stat = true;
break;
case 'D':
match_opts.dot = true;
break;
}
}