[master] b55cfa1 Make help -j output real JSON, and push backend.list -j into the schema intended for JSON output.

Poul-Henning Kamp phk at FreeBSD.org
Sun May 13 20:53:21 UTC 2018


commit b55cfa1bee60f14314e9a70da58350299c922d15
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Sun May 13 20:52:10 2018 +0000

    Make help -j output real JSON, and push backend.list -j into
    the schema intended for JSON output.

diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index cc3eef8..5b553d2 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -422,7 +422,7 @@ vbe_list(const struct director *d, struct vsb *vsb, int vflag, int pflag,
 	if (bp->probe != NULL)
 		VBP_Status(vsb, bp, vflag | pflag, jflag);
 	else if ((vflag | pflag) == 0 && jflag)
-		VSB_printf(vsb, "\"%s\",\n", d->sick ? "sick" : "healthy");
+		VSB_printf(vsb, "\"%s\"", d->sick ? "sick" : "healthy");
 	else
 		VSB_printf(vsb, "%-10s", d->sick ? "sick" : "healthy");
 }
diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c
index 2299d1b..9eb7a7f 100644
--- a/bin/varnishd/cache/cache_backend_probe.c
+++ b/bin/varnishd/cache/cache_backend_probe.c
@@ -483,27 +483,27 @@ VBP_Status(struct vsb *vsb, const struct backend *be, int details, int json)
 	CHECK_OBJ_NOTNULL(vt, VBP_TARGET_MAGIC);
 
 	if (!details) {
-		if (json) {
-			VSB_printf(vsb, "[%u, %u, \"%s\"]",
-			    vt->good, vt->window, 
-			    vt->backend->director->sick ? "bad" : "good");
-		} else {
-			bprintf(buf, "%u/%u %s", vt->good, vt->window,
-			    vt->backend->director->sick ? "bad" : "good");
+		bprintf(buf, "%u/%u %s", vt->good, vt->window,
+		    vt->backend->director->sick ? "bad" : "good");
+		if (json)
+			VSB_printf(vsb, "\"%s\"", buf);
+		else
 			VSB_printf(vsb, "%-10s", buf);
-		}
 		return;
 	}
 
 	if (json) {
 		VSB_printf(vsb, "{\n");
+		VSB_indent(vsb, 2);
 #define BITMAP(nn, cc, tt, bb)					\
-		VSB_printf(vsb, "\t    \"bits_%c\": %ju,\n", cc, vt->nn);
+		VSB_printf(vsb, "\"bits_%c\": %ju,\n", cc, vt->nn);
 #include "tbl/backend_poll.h"
-		VSB_printf(vsb, "\t    \"good\": %u,\n", vt->good);
-		VSB_printf(vsb, "\t    \"threshold\": %u,\n", vt->threshold);
-		VSB_printf(vsb, "\t    \"window\": %u\n", vt->window);
-		VSB_printf(vsb, "\t    },\n");
+		VSB_printf(vsb, "\"good\": %u,\n", vt->good);
+		VSB_printf(vsb, "\"threshold\": %u,\n", vt->threshold);
+		VSB_printf(vsb, "\"window\": %u", vt->window);
+		VSB_indent(vsb, -2);
+		VSB_printf(vsb, "\n");
+		VSB_printf(vsb, "},\n");
 		return;
 	}
 
diff --git a/bin/varnishd/cache/cache_director.c b/bin/varnishd/cache/cache_director.c
index 51723a0..a80f751 100644
--- a/bin/varnishd/cache/cache_director.c
+++ b/bin/varnishd/cache/cache_director.c
@@ -316,12 +316,14 @@ do_list_json(struct cli *cli, struct director *d, void *priv)
 		return (0);
 
 	VCLI_Out(cli, "%s", la->jsep);
-	la->jsep = ",\n    ";
+	la->jsep = ",\n";
 	// XXX admin health "probe" for the no-probe case is confusing
-	VCLI_Out(cli, "\"%s\": {\n", d->vdir->cli_name);
-	VCLI_Out(cli, "\t\"type\": \"%s\",\n", d->vdir->methods->type);
-	VCLI_Out(cli, "\t\"admin_health\": \"%s\",\n", VDI_Ahealth(d));
-	VCLI_Out(cli, "\t\"probe_health\": ");
+	VCLI_JSON_str(cli, d->vdir->cli_name);
+	VCLI_Out(cli, ": {\n");
+	VSB_indent(cli->sb, 2);
+	VCLI_Out(cli, "\"type\": \"%s\",\n", d->vdir->methods->type);
+	VCLI_Out(cli, "\"admin_health\": \"%s\",\n", VDI_Ahealth(d));
+	VCLI_Out(cli, "\"probe_message\": ");
 	if (d->vdir->methods->list != NULL)
 		d->vdir->methods->list(d, cli->sb, 0, 0, 1);
 	else
@@ -329,11 +331,12 @@ do_list_json(struct cli *cli, struct director *d, void *priv)
 	VCLI_Out(cli, ",\n");
 
 	if ((la->p || la->v) && d->vdir->methods->list != NULL) {
-		VCLI_Out(cli, "\t\"probe_details\": ");
+		VCLI_Out(cli, "\"probe_details\": ");
 		d->vdir->methods->list(d, cli->sb, la->p, la->v, 1);
 	}
-	VCLI_Out(cli, "\t\"last_change\": %.3f\n    }",
-	    d->vdir->health_changed);
+	VCLI_Out(cli, "\"last_change\": %.3f\n", d->vdir->health_changed);
+	VSB_indent(cli->sb, -2);
+	VCLI_Out(cli, "}");
 	return (0);
 }
 
@@ -342,13 +345,14 @@ cli_backend_list(struct cli *cli, const char * const *av, void *priv)
 {
 	const char *p;
 	struct list_args la[1];
+	int i;
 
 	(void)priv;
 	ASSERT_CLI();
 	INIT_OBJ(la, LIST_ARGS_MAGIC);
-	la->jsep = "\n    ";
-	while (av[2] != NULL && av[2][0] == '-') {
-		for(p = av[2] + 1; *p; p++) {
+	la->jsep = "";
+	for (i = 2; av[i] != NULL && av[i][0] == '-'; i++) {
+		for(p = av[i] + 1; *p; p++) {
 			switch(*p) {
 			case 'j': la->j = 1; break;
 			case 'p': la->p = !la->p; break;
@@ -359,21 +363,26 @@ cli_backend_list(struct cli *cli, const char * const *av, void *priv)
 				return;
 			}
 		}
-		av++;
 	}
-	if (av[3] != NULL) {
+	if (av[i] != NULL && av[i+1] != NULL) {
 		VCLI_Out(cli, "Too many arguments");
 		VCLI_SetResult(cli, CLIS_PARAM);
 		return;
 	}
 	if (la->j) {
-		VCLI_Out(cli, "{");
-		(void)VCL_IterDirector(cli, av[2], do_list_json, la);
-		VCLI_Out(cli, "\n}\n");
+		VCLI_JSON_begin(cli, 1, av);
+		VCLI_Out(cli, ",\n");
+		VCLI_Out(cli, "{\n");
+		VSB_indent(cli->sb, 2);
+		(void)VCL_IterDirector(cli, av[i], do_list_json, la);
+		VSB_indent(cli->sb, -2);
+		VCLI_Out(cli, "\n");
+		VCLI_Out(cli, "}");
+		VCLI_JSON_end(cli);
 	} else {
 		VCLI_Out(cli, "%-30s %-7s %-10s %s",
 		    "Backend name", "Admin", "Probe", "Last change");
-		(void)VCL_IterDirector(cli, av[2], do_list, la);
+		(void)VCL_IterDirector(cli, av[i], do_list, la);
 	}
 }
 
diff --git a/bin/varnishtest/tests/b00008.vtc b/bin/varnishtest/tests/b00008.vtc
index e536a81..1ec3611 100644
--- a/bin/varnishtest/tests/b00008.vtc
+++ b/bin/varnishtest/tests/b00008.vtc
@@ -26,7 +26,7 @@ varnish v1 -start
 
 varnish v1 -cliok "help"
 
-varnish v1 -cliok "help -j"
+varnish v1 -clijson "help -j"
 
 varnish v1 -clierr 106 "param.set waiter HASH(0x8839c4c)"
 
diff --git a/bin/varnishtest/tests/d00005.vtc b/bin/varnishtest/tests/d00005.vtc
index 202b57b..3b249e5 100644
--- a/bin/varnishtest/tests/d00005.vtc
+++ b/bin/varnishtest/tests/d00005.vtc
@@ -96,4 +96,4 @@ client c1 {
 } -run
 
 varnish v1 -vsl_catchup
-varnish v1 -cliok "backend.list -j"
+varnish v1 -clijson "backend.list -j"
diff --git a/bin/varnishtest/tests/v00014.vtc b/bin/varnishtest/tests/v00014.vtc
index 7b9212a..ea41802 100644
--- a/bin/varnishtest/tests/v00014.vtc
+++ b/bin/varnishtest/tests/v00014.vtc
@@ -50,7 +50,7 @@ varnish v1 -vcl {
 } -start
 
 varnish v1 -cliok "backend.list -p"
-varnish v1 -cliok "backend.list -j -p"
+varnish v1 -clijson "backend.list -j -p"
 
 client c1 {
 	txreq
diff --git a/include/vcli_serve.h b/include/vcli_serve.h
index 7bc04c3..8378993 100644
--- a/include/vcli_serve.h
+++ b/include/vcli_serve.h
@@ -85,7 +85,8 @@ int VCLI_Overflow(struct cli *cli);
 void VCLI_Out(struct cli *cli, const char *fmt, ...) v_printflike_(2, 3);
 void VCLI_Quote(struct cli *cli, const char *str);
 void VCLI_JSON_str(struct cli *cli, const char *str);
-void VCLI_JSON_ver(struct cli *cli, unsigned ver, const char * const * av);
+void VCLI_JSON_begin(struct cli *cli, unsigned ver, const char * const * av);
+void VCLI_JSON_end(struct cli *cli);
 void VCLI_SetResult(struct cli *cli, unsigned r);
 
 typedef int cls_cb_f(void *priv);
diff --git a/lib/libvarnish/vcli_serve.c b/lib/libvarnish/vcli_serve.c
index 67c6816..5171d31 100644
--- a/lib/libvarnish/vcli_serve.c
+++ b/lib/libvarnish/vcli_serve.c
@@ -159,26 +159,35 @@ VCLS_func_help_json(struct cli *cli, const char * const *av, void *priv)
 	cs = cli->cls;
 	CHECK_OBJ_NOTNULL(cs, VCLS_MAGIC);
 
-	VCLI_JSON_ver(cli, 1, av);
+	VCLI_JSON_begin(cli, 1, av);
 	VTAILQ_FOREACH(clp, &cs->funcs, list) {
 		if (clp->auth > cli->auth)
 			continue;
-		VCLI_Out(cli, ",\n  {");
-		VCLI_Out(cli, "\n  \"request\": ");
+		VCLI_Out(cli, ",\n  {\n");
+		VSB_indent(cli->sb, 2);
+		VCLI_Out(cli, "\"request\": ");
 		VCLI_JSON_str(cli, clp->desc->request);
-		VCLI_Out(cli, ",\n  \"syntax\": ");
+		VCLI_Out(cli, ",\n");
+		VCLI_Out(cli, "\"syntax\": ");
 		VCLI_JSON_str(cli, clp->desc->syntax);
-		VCLI_Out(cli, ",\n  \"help\": ");
+		VCLI_Out(cli, ",\n");
+		VCLI_Out(cli, "\"help\": ");
 		VCLI_JSON_str(cli, clp->desc->help);
-		VCLI_Out(cli, ",\n  \"minarg\": %d", clp->desc->minarg);
-		VCLI_Out(cli, ", \"maxarg\": %d", clp->desc->maxarg);
-		VCLI_Out(cli, ", \"flags\": ");
+		VCLI_Out(cli, ",\n");
+		VCLI_Out(cli, "\"minarg\": %d", clp->desc->minarg);
+		VCLI_Out(cli, ",\n");
+		VCLI_Out(cli, "\"maxarg\": %d", clp->desc->maxarg);
+		VCLI_Out(cli, ",\n");
+		VCLI_Out(cli, "\"flags\": ");
 		VCLI_JSON_str(cli, clp->flags);
-		VCLI_Out(cli, ", \"json\": %s",
+		VCLI_Out(cli, ",\n");
+		VCLI_Out(cli, "\"json\": %s",
 		    clp->jsonfunc == NULL ? "false" : "true");
-		VCLI_Out(cli, "\n  }");
+		VCLI_Out(cli, "\n");
+		VSB_indent(cli->sb, -2);
+		VCLI_Out(cli, "}");
 	}
-	VCLI_Out(cli, "\n]\n");
+	VCLI_JSON_end(cli);
 }
 
 /*--------------------------------------------------------------------
@@ -641,12 +650,14 @@ VCLI_JSON_str(struct cli *cli, const char *s)
 {
 
 	CHECK_OBJ_NOTNULL(cli, CLI_MAGIC);
+	VSB_putc(cli->sb, '"');
 	VSB_quote(cli->sb, s, -1, VSB_QUOTE_JSON);
+	VSB_putc(cli->sb, '"');
 }
 
 /*lint -e{818} cli could be const */
 void
-VCLI_JSON_ver(struct cli *cli, unsigned ver, const char * const * av)
+VCLI_JSON_begin(struct cli *cli, unsigned ver, const char * const * av)
 {
 	int i;
 
@@ -658,6 +669,15 @@ VCLI_JSON_ver(struct cli *cli, unsigned ver, const char * const * av)
 			VCLI_Out(cli, ", ");
 	}
 	VCLI_Out(cli, "]");
+	VSB_indent(cli->sb, 2);
+}
+
+void
+VCLI_JSON_end(struct cli *cli)
+{
+	VSB_indent(cli->sb, -2);
+	VCLI_Out(cli, "\n");
+	VCLI_Out(cli, "]\n");
 }
 
 /*lint -e{818} cli could be const */


More information about the varnish-commit mailing list