From e580d84597d0f4e2e2d24a1c0d083ebb2153eee2 Mon Sep 17 00:00:00 2001 From: Walid Boudebouda Date: Fri, 3 Mar 2023 11:21:50 +0100 Subject: [PATCH] cli: allow loading multiple files with vcl.load This commit adds the ability to specify multiple vcl files with vcl.load cli command: vcl.load [-s auto|cold|warm] [-p vcl_path] [file2, ...] --- bin/varnishd/mgt/mgt.h | 2 +- bin/varnishd/mgt/mgt_vcc.c | 8 ++--- bin/varnishd/mgt/mgt_vcl.c | 13 ++++---- bin/varnishtest/tests/c00124.vtc | 53 ++++++++++++++++++++++++++++++++ include/libvcc.h | 2 +- include/tbl/cli_cmds.h | 4 +-- lib/libvcc/vcc_compile.c | 43 +++++++++++++++++--------- 7 files changed, 97 insertions(+), 28 deletions(-) create mode 100644 bin/varnishtest/tests/c00124.vtc diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h index 7141472fa8b..ecd18a30570 100644 --- a/bin/varnishd/mgt/mgt.h +++ b/bin/varnishd/mgt/mgt.h @@ -225,7 +225,7 @@ void STV_Init(void); /* mgt_vcc.c */ void mgt_DumpBuiltin(void); char *mgt_VccCompile(struct cli *, struct vclprog *, const char *vclname, - const char *vclsrc, const char *vclsrcfile, const char *vcl_path, int C_flag); + const char *vclsrc, const char * const *vclsrcfiles, const char *vcl_path, int C_flag); void mgt_vcl_init(void); void mgt_vcl_startup(struct cli *, const char *vclsrc, const char *origin, diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c index 0ca91d5cd8a..b12ffbcb0ec 100644 --- a/bin/varnishd/mgt/mgt_vcc.c +++ b/bin/varnishd/mgt/mgt_vcc.c @@ -56,7 +56,7 @@ struct vcc_priv { unsigned magic; #define VCC_PRIV_MAGIC 0x70080cb8 const char *vclsrc; - const char *vclsrcfile; + const char* const *vclsrcfiles; const char *vcl_path; struct vsb *dir; struct vsb *csrcfile; @@ -142,7 +142,7 @@ run_vcc(void *priv) VTAILQ_FOREACH(vpg, &vclhead, list) if (mcf_is_label(vpg)) VCC_Predef(vcc, "VCL_VCL", vpg->name); - i = VCC_Compile(vcc, &sb, vp->vclsrc, vp->vclsrcfile, + i = VCC_Compile(vcc, &sb, vp->vclsrc, vp->vclsrcfiles, VGC_SRC, VGC_SYM); if (VSB_len(sb)) printf("%s", VSB_data(sb)); @@ -357,7 +357,7 @@ mgt_vcc_fini_vp(struct vcc_priv *vp, int leave_lib) char * mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname, - const char *vclsrc, const char *vclsrcfile, const char* vcl_path, int C_flag) + const char *vclsrc, const char * const *vclsrcfiles, const char* vcl_path, int C_flag) { struct vcc_priv vp[1]; struct vsb *sb; @@ -371,7 +371,7 @@ mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname, mgt_vcc_init_vp(vp); vp->vclsrc = vclsrc; - vp->vclsrcfile = vclsrcfile; + vp->vclsrcfiles = vclsrcfiles; vp->vcl_path = vcl_path; /* diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index 810b03a67d4..8dee34ae34e 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -437,7 +437,7 @@ mgt_vcl_setstate(struct cli *cli, struct vclprog *vp, const struct vclstate *vs) static struct vclprog * mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, - const char *vclsrcfile, const char *state, const char* vcl_path, int C_flag) + const char * const *vclsrcfiles, const char *state, const char* vcl_path, int C_flag) { unsigned status; char *lib, *p; @@ -463,7 +463,7 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, return (NULL); vp = mgt_vcl_add(vclname, vs); - lib = mgt_VccCompile(cli, vp, vclname, vclsrc, vclsrcfile, vcl_path, C_flag); + lib = mgt_VccCompile(cli, vp, vclname, vclsrc, vclsrcfiles, vcl_path, C_flag); if (lib == NULL) { mgt_vcl_del(vp); return (NULL); @@ -506,7 +506,7 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname, char buf[20]; static int n = 0; struct vclprog *vp; - + const char *vcls[] = {origin, NULL}; AZ(MCH_Running()); AN(vclsrc); @@ -515,7 +515,7 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname, bprintf(buf, "boot%d", n++); vclname = buf; } - vp = mgt_new_vcl(cli, vclname, vclsrc, origin, NULL, NULL, C_flag); + vp = mgt_new_vcl(cli, vclname, vclsrc, vcls, NULL, NULL, C_flag); if (vp != NULL) { /* Last startup VCL becomes the automatically selected * active VCL. */ @@ -589,6 +589,7 @@ mcf_vcl_inline(struct cli *cli, const char * const *av, void *priv) { struct vclprog *vp; const char* state = NULL; + const char *vcls[] = {"", NULL}; int i = 2; (void)priv; @@ -607,7 +608,7 @@ mcf_vcl_inline(struct cli *cli, const char * const *av, void *priv) if (!mcf_find_no_vcl(cli, av[i])) return; - vp = mgt_new_vcl(cli, av[i], av[i+1], "", state, NULL, 0); + vp = mgt_new_vcl(cli, av[i], av[i+1], vcls, state, NULL, 0); if (vp != NULL && !MCH_Running()) VCLI_Out(cli, "VCL compiled.\n"); } @@ -644,7 +645,7 @@ mcf_vcl_load(struct cli *cli, const char * const *av, void *priv) if (!mcf_find_no_vcl(cli, av[i])) return; - vp = mgt_new_vcl(cli, av[i], NULL, av[i+1], state, vcl_path, 0); + vp = mgt_new_vcl(cli, av[i], NULL, &av[i+1], state, vcl_path, 0); if (vp != NULL && !MCH_Running()) VCLI_Out(cli, "VCL compiled.\n"); } diff --git a/bin/varnishtest/tests/c00124.vtc b/bin/varnishtest/tests/c00124.vtc new file mode 100644 index 00000000000..9566c9cedf3 --- /dev/null +++ b/bin/varnishtest/tests/c00124.vtc @@ -0,0 +1,53 @@ +varnishtest "Test vcl.load with multiple vcl files" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend {} -start + +shell { + ( + echo 'vcl 4.0;' + echo 'backend default {' + echo ' .host="${s1_addr}";' + echo ' .port="${s1_port}";' + echo '}' + echo '' + echo 'sub vcl_deliver {' + echo ' set resp.http.test1 = "test1";' + echo '}' + ) > ${tmpdir}/file1.vcl +} + +shell { + ( + echo 'vcl 4.0;' + echo 'sub vcl_deliver {' + echo ' set resp.http.test2 = "test2";' + echo '}' + ) > ${tmpdir}/file2.vcl +} + +shell { + ( + echo 'vcl 4.0;' + echo 'sub vcl_deliver {' + echo ' set resp.http.test3 = "test3";' + echo '}' + ) > ${tmpdir}/file3.vcl +} + +varnish v1 -cliok {vcl.load -s cold foo ${tmpdir}/file1.vcl ${tmpdir}/file2.vcl ${tmpdir}/file3.vcl} +varnish v1 -cliexpect "VCL 'foo' is cold" {vcl.use foo} +varnish v1 -cliok {vcl.state foo warm} +varnish v1 -cliok {vcl.use foo} + +client c1 { + txreq + rxresp + expect resp.http.test1 == "test1" + expect resp.http.test2 == "test2" + expect resp.http.test3 == "test3" +} -run \ No newline at end of file diff --git a/include/libvcc.h b/include/libvcc.h index 852fe91b06d..8be6f50d6f7 100644 --- a/include/libvcc.h +++ b/include/libvcc.h @@ -45,4 +45,4 @@ void VCC_VEXT(struct vcc *, const char *); #include "tbl/vcc_feature_bits.h" int VCC_Compile(struct vcc *, struct vsb **, - const char *, const char *, const char *, const char *); + const char *, const char *const *, const char *, const char *); diff --git a/include/tbl/cli_cmds.h b/include/tbl/cli_cmds.h index 38e1f1b5e28..fd09a1de424 100644 --- a/include/tbl/cli_cmds.h +++ b/include/tbl/cli_cmds.h @@ -72,10 +72,10 @@ CLI_CMD(BAN_LIST, CLI_CMD(VCL_LOAD, "vcl.load", - "vcl.load [-s auto|cold|warm] [-p vcl_path] ", + "vcl.load [-s auto|cold|warm] [-p vcl_path] [filename2, ...]", "Compile and load the VCL file under the name provided.", "", - 2, 6 + 2, -1 ) CLI_CMD(VCL_INLINE, diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c index f3f9a2d70e7..f4dc32a7983 100644 --- a/lib/libvcc/vcc_compile.c +++ b/lib/libvcc/vcc_compile.c @@ -611,11 +611,12 @@ EmitStruct(const struct vcc *tl) */ static struct vsb * -vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile) +vcc_CompileSource(struct vcc *tl, struct source **sps, const char *jfile) { struct proc *p; struct vsb *vsb; struct inifin *ifp; + struct source *sp; Fh(tl, 0, "/* ---===### VCC generated .h code ###===---*/\n"); Fc(tl, 0, "\n/* ---===### VCC generated .c code ###===---*/\n"); @@ -637,11 +638,15 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile) Fh(tl, 0, "\nextern const struct VCL_conf VCL_conf;\n"); /* Register and lex the main source */ - if (sp != NULL) { - AN(vcc_builtin); - vcc_lex_source(tl, sp, 0); - if (tl->err) - return (NULL); + + if (sps != NULL && *sps != NULL) { + while (*sps != NULL) { + AN(vcc_builtin); + vcc_lex_source(tl, *sps, 0); + if (tl->err) + return (NULL); + sps++; + } } /* Register and lex the builtin VCL */ @@ -770,19 +775,26 @@ VCC_VCL_Range(unsigned *lo, unsigned *hi) int VCC_Compile(struct vcc *tl, struct vsb **sb, - const char *vclsrc, const char *vclsrcfile, + const char *vclsrc, const char * const *vclsrcfiles, const char *ofile, const char *jfile) { - struct source *sp; + struct source **sp; struct vsb *r = NULL; - int retval = 0; + int retval = 0, n = 1; CHECK_OBJ_NOTNULL(tl, VCC_MAGIC); AN(sb); - AN(vclsrcfile); + AN(vclsrcfiles); + AN(*vclsrcfiles); AN(ofile); AN(jfile); + while (vclsrcfiles[n-1]) + n++; + sp = calloc(n, sizeof(struct source*)); + AN(sp); + sp[n-1] = NULL; + AZ(vcc_builtin); vcc_builtin = vcc_ParseBuiltin(tl); AN(vcc_builtin); @@ -793,11 +805,13 @@ VCC_Compile(struct vcc *tl, struct vsb **sb, } if (vclsrc != NULL) - sp = vcc_new_source(vclsrc, "vcl.inline", vclsrcfile); - else - sp = vcc_file_source(tl, vclsrcfile); + sp[0] = vcc_new_source(vclsrc, "vcl.inline", *vclsrcfiles); + else { + for (int i=0; vclsrcfiles[i]; i++) + sp[i] = vcc_file_source(tl, vclsrcfiles[i]); + } - if (sp != NULL) + if (sp[0] != NULL) r = vcc_CompileSource(tl, sp, jfile); if (r != NULL) { @@ -808,6 +822,7 @@ VCC_Compile(struct vcc *tl, struct vsb **sb, } AZ(VSB_finish(tl->sb)); *sb = tl->sb; + free(sp); return (retval); }