[master] f7aeba94f cli: New vcl.deps [-j] command

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Mon Nov 23 05:15:15 UTC 2020


commit f7aeba94f089d22256d56ff6935cbc2b9e64e06e
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Wed Aug 5 09:34:45 2020 +0200

    cli: New vcl.deps [-j] command
    
    The plain text output is a suitable input for tsort(1), initially
    meant to find the correct discard order, I realized that it would
    be more reliable to let vcl.discard figure that one out.
    
    It wouldn't really work in my initial scenario:
    
        varnishadm vcl.deps |
        <filter some VCLs out> |
        tsort |
        xargs -n 1 varnishadm vcl.discard
    
    The filtering part only worked for direct dependencies but we can
    have two levels with return(vcl).
    
    I'm keeping this command only for setup analysis, the output can
    easily be turned into a graphviz dot file for example.

diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index af4cffc11..4eb713320 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -1006,6 +1006,66 @@ mcf_vcl_label(struct cli *cli, const char * const *av, void *priv)
 	free(p);
 }
 
+static void v_matchproto_(cli_func_t)
+mcf_vcl_deps(struct cli *cli, const char * const *av, void *priv)
+{
+	struct vclprog *vp;
+	struct vcldep *vd;
+	struct vsb *vsb;
+
+	(void)av;
+	(void)priv;
+
+	vsb = VSB_new_auto();
+	AN(vsb);
+
+	VTAILQ_FOREACH(vp, &vclhead, list) {
+		if (VTAILQ_EMPTY(&vp->dfrom)) {
+			VSB_printf(vsb, "%s\n", vp->name);
+			continue;
+		}
+		VTAILQ_FOREACH(vd, &vp->dfrom, lfrom)
+			VSB_printf(vsb, "%s\t%s\n", vp->name, vd->to->name);
+	}
+	VCLI_VTE(cli, &vsb, 80);
+}
+
+static void v_matchproto_(cli_func_t)
+mcf_vcl_deps_json(struct cli *cli, const char * const *av, void *priv)
+{
+	struct vclprog *vp;
+	struct vcldep *vd;
+	const char *sepd, *sepa;
+
+	(void)priv;
+
+	VCLI_JSON_begin(cli, 1, av);
+
+	VTAILQ_FOREACH(vp, &vclhead, list) {
+		VCLI_Out(cli, ",\n");
+		VCLI_Out(cli, "{\n");
+		VSB_indent(cli->sb, 2);
+		VCLI_Out(cli, "\"name\": \"%s\",\n", vp->name);
+		VCLI_Out(cli, "\"deps\": [");
+		VSB_indent(cli->sb, 2);
+		sepd = "";
+		sepa = "";
+		VTAILQ_FOREACH(vd, &vp->dfrom, lfrom) {
+			VCLI_Out(cli, "%s\n", sepd);
+			VCLI_Out(cli, "\"%s\"", vd->to->name);
+			sepd = ",";
+			sepa = "\n";
+		}
+		VSB_indent(cli->sb, -2);
+		VCLI_Out(cli, "%s", sepa);
+		VCLI_Out(cli, "]\n");
+		VSB_indent(cli->sb, -2);
+		VCLI_Out(cli, "}");
+	}
+
+	VCLI_JSON_end(cli);
+}
+
 /*--------------------------------------------------------------------*/
 
 static int v_matchproto_(vev_cb_f)
@@ -1037,6 +1097,7 @@ static struct cli_proto cli_vcl[] = {
 	{ CLICMD_VCL_STATE,		"", mcf_vcl_state },
 	{ CLICMD_VCL_DISCARD,		"", mcf_vcl_discard },
 	{ CLICMD_VCL_LIST,		"", mcf_vcl_list, mcf_vcl_list_json },
+	{ CLICMD_VCL_DEPS,		"", mcf_vcl_deps, mcf_vcl_deps_json },
 	{ CLICMD_VCL_LABEL,		"", mcf_vcl_label },
 	{ CLICMD_DEBUG_VCL_SYMTAB,	"d", mcf_vcl_symtab },
 	{ NULL }
diff --git a/include/tbl/cli_cmds.h b/include/tbl/cli_cmds.h
index 6fef4be1f..02d853b68 100644
--- a/include/tbl/cli_cmds.h
+++ b/include/tbl/cli_cmds.h
@@ -125,6 +125,20 @@ CLI_CMD(VCL_LIST,
 	0, 0
 )
 
+CLI_CMD(VCL_DEPS,
+	"vcl.deps",
+	"vcl.deps [-j]",
+	"List all loaded configuration and their dependencies.",
+	"  Unless ``-j`` is specified for JSON output, the"
+	" output format is up to two columns of dynamic width"
+	" separated by white space with the fields:\n\n"
+	"  * VCL: a VCL program\n\n"
+	"  * Dependency: another VCL program it depends on\n\n"
+	"Only direct dependencies are listed, and VCLs with"
+	" multiple dependencies are listed multiple times.",
+	0, 0
+)
+
 CLI_CMD(VCL_SHOW,
 	"vcl.show",
 	"vcl.show [-v] <configname>",


More information about the varnish-commit mailing list