From: Radosław Korzeniewski Date: Tue, 29 Jun 2021 15:22:59 +0000 (+0200) Subject: metaplugin: Extend query interface for unstructured data. X-Git-Tag: Release-11.3.2~443 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ad847499862376f7d22a8995f63c3021bf5c0f9;p=thirdparty%2Fbacula.git metaplugin: Extend query interface for unstructured data. Now you can use a `Data` packet to respond with any data for queryParameter() API. This data will be simply forwarded to Bacula without scanning and interpretation by metaplugin. --- diff --git a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp index ce15c27d3..bc4629540 100644 --- a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp +++ b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp @@ -2437,13 +2437,6 @@ bRC METAPLUGIN::handleXACLdata(bpContext *ctx, struct xacl_pkt *xacl) */ bRC METAPLUGIN::queryParameter(bpContext *ctx, struct query_pkt *qp) { - bRC ret = bRC_More; - OutputWriter ow(qp->api_opts); - POOL_MEM cmd(PM_MESSAGE); - char *p, *q, *t; - alist values(10, not_owned_by_alist); - key_pair *kp; - DMSG0(ctx, D1, "METAPLUGIN::queryParameter\n"); // check if it is our Plugin command @@ -2460,6 +2453,8 @@ bRC METAPLUGIN::queryParameter(bpContext *ctx, struct query_pkt *qp) } } + POOL_MEM cmd(PM_MESSAGE); + if (listing == None) { listing = Query; Mmsg(cmd, "%s query=%s", qp->command, qp->parameter); @@ -2469,12 +2464,16 @@ bRC METAPLUGIN::queryParameter(bpContext *ctx, struct query_pkt *qp) } /* read backend response */ - if (backend.ctx->read_command(ctx, cmd) < 0){ + char pkt = 0; + int32_t pktlen = backend.ctx->read_any(ctx, &pkt, cmd); + if (pktlen < 0) { DMSG(ctx, DERROR, "Cannot read backend query response for %s command.\n", qp->parameter); JMSG(ctx, backend.ctx->jmsg_err_level(), "Cannot read backend query response for %s command.\n", qp->parameter); return bRC_Error; } + bRC ret = bRC_More; + /* check EOD */ if (backend.ctx->is_eod()){ /* got EOD so the backend finish response, so terminate the chat */ @@ -2484,48 +2483,72 @@ bRC METAPLUGIN::queryParameter(bpContext *ctx, struct query_pkt *qp) qp->result = NULL; ret = bRC_OK; } else { - /* - * here we have: - * key=value[,key2=value2[,...]] - * parameters we should decompose - */ - p = cmd.c_str(); - while (*p != '\0'){ - q = strchr(p, ','); - if (q != NULL){ - *q++ = '\0'; - } - // single key=value - DMSG(ctx, D1, "METAPLUGIN::queryParameter:scan %s\n", p); - if ((t = strchr(p, '=')) != NULL){ - *t++ = '\0'; - } else { - t = (char*)""; // pointer to empty string - } - DMSG2(ctx, D1, "METAPLUGIN::queryParameter:pair '%s' = '%s'\n", p, t); - if (strlen(p) > 0){ - // push values only when we have key name - kp = New(key_pair(p, t)); - values.append(kp); - } - p = q != NULL ? q : (char*)""; - } + switch (pkt) + { + case 'C': + { + OutputWriter ow(qp->api_opts); + char *p, *q, *t; + alist values(10, not_owned_by_alist); + key_pair *kp; + + /* + * here we have: + * key=value[,key2=value2[,...]] + * parameters we should decompose + */ + p = cmd.c_str(); + while (*p != '\0') { + q = strchr(p, ','); + if (q != NULL) { + *q++ = '\0'; + } + // single key=value + DMSG(ctx, D1, "METAPLUGIN::queryParameter:scan %s\n", p); + if ((t = strchr(p, '=')) != NULL) { + *t++ = '\0'; + } else { + t = (char*)""; // pointer to empty string + } + DMSG2(ctx, D1, "METAPLUGIN::queryParameter:pair '%s' = '%s'\n", p, t); + if (strlen(p) > 0) { + // push values only when we have key name + kp = New(key_pair(p, t)); + values.append(kp); + } + p = q != NULL ? q : (char*)""; + } - // if more values then one then it is a list - if (values.size() > 1){ - DMSG0(ctx, D1, "METAPLUGIN::queryParameter: will render list\n") - ow.start_list(qp->parameter); - } - // render all values - foreach_alist(kp, &values){ - ow.get_output(OT_STRING, kp->key.c_str(), kp->value.c_str(), OT_END); - delete kp; - } - if (values.size() > 1){ - ow.end_list(); + // if more values then one then it is a list + if (values.size() > 1) { + DMSG0(ctx, D1, "METAPLUGIN::queryParameter: will render list\n") + ow.start_list(qp->parameter); + } + // render all values + foreach_alist(kp, &values) { + ow.get_output(OT_STRING, kp->key.c_str(), kp->value.c_str(), OT_END); + delete kp; + } + if (values.size() > 1) { + ow.end_list(); + } + pm_strcpy(robjbuf, ow.get_output(OT_END)); + qp->result = robjbuf.c_str(); + } + break; + case 'D': + pm_memcpy(robjbuf, cmd.c_str(), pktlen); + qp->result = robjbuf.c_str(); + break; + default: + DMSG(ctx, DERROR, "METAPLUGIN::queryParameter: got invalid packet: %c\n", pkt); + JMSG(ctx, M_ERROR, "METAPLUGIN::queryParameter: got invalid packet: %c\n", pkt); + backend.ctx->signal_term(ctx); + backend.ctx->terminate(ctx); + qp->result = NULL; + ret = bRC_Error; + break; } - pm_strcpy(robjbuf, ow.get_output(OT_END)); - qp->result = robjbuf.c_str(); } return ret; diff --git a/bacula/src/plugins/fd/pluginlib/ptcomm.cpp b/bacula/src/plugins/fd/pluginlib/ptcomm.cpp index 4c5cfce89..2d83d183e 100644 --- a/bacula/src/plugins/fd/pluginlib/ptcomm.cpp +++ b/bacula/src/plugins/fd/pluginlib/ptcomm.cpp @@ -282,14 +282,20 @@ bool PTCOMM::sendbackend_data(bpContext *ctx, POOLMEM *buf, int32_t nbytes) * @param cmd - an expected command to read: `C` or `D` * @return int32_t - the size of the packet payload */ -int32_t PTCOMM::recvbackend_header(bpContext *ctx, char cmd) +int32_t PTCOMM::recvbackend_header(bpContext *ctx, char *cmd, bool any) { - if (is_closed()){ + if (is_closed()) { DMSG0(ctx, DERROR, "BPIPE to backend is closed, cannot receive data.\n"); JMSG0(ctx, is_fatal() ? M_FATAL : M_ERROR, "BPIPE to backend is closed, cannot receive data.\n"); return -1; } + if (cmd == NULL) { + DMSG0(ctx, DERROR, "Runtime error. cmd == NULL. Cannot read data.\n"); + JMSG0(ctx, is_fatal() ? M_FATAL : M_ERROR, "Runtime error. cmd == NULL. Cannot read data.\n"); + return -1; + } + PTHEADER header; bool workdone = false; @@ -326,15 +332,16 @@ int32_t PTCOMM::recvbackend_header(bpContext *ctx, char cmd) // convert packet length from ASCII to binary int32_t msglen = atoi(header.length); - if (header.status == 'C' || header.status == 'D') - { - if (header.status != cmd) - { - DMSG2(ctx, DERROR, "Protocol error. Expected packet: %c got: %c\n", cmd, header.status); - JMSG2(ctx, M_FATAL, "Protocol error. Expected packet: %c got: %c\n", cmd, header.status); - return -1; + if (header.status == 'C' || header.status == 'D') { + if (!any) { + if (header.status != *cmd) { + DMSG2(ctx, DERROR, "Protocol error. Expected packet: %c got: %c\n", *cmd, header.status); + JMSG2(ctx, M_FATAL, "Protocol error. Expected packet: %c got: %c\n", *cmd, header.status); + return -1; + } + } else { + *cmd = header.status; } - // this means no additional handling required return msglen; } @@ -440,14 +447,13 @@ int32_t PTCOMM::recvbackend_header(bpContext *ctx, char cmd) * @param cmd * @return int32_t */ -int32_t PTCOMM::handle_read_header(bpContext *ctx, char cmd) +int32_t PTCOMM::handle_read_header(bpContext *ctx, char *cmd, bool any) { // first read is the packet header where we will have info about data // which is sent to us; the packet header is 8 chars/bytes length fixed // nbytes shows how many bytes we expects to read - int32_t length = recvbackend_header(ctx, cmd); - if (length < 0) - { + int32_t length = recvbackend_header(ctx, cmd, any); + if (length < 0) { // error DMSG0(ctx, DERROR, "PTCOMM cannot get packet header from backend.\n"); JMSG0(ctx, is_fatal() ? M_FATAL : M_ERROR, "PTCOMM cannot get packet header from backend.\n"); @@ -502,16 +508,16 @@ int32_t PTCOMM::handle_payload(bpContext *ctx, char *buf, int32_t nbytes) * ctx is not NULL * : the size of received message */ -int32_t PTCOMM::recvbackend(bpContext *ctx, char cmd, POOL_MEM &buf) +int32_t PTCOMM::recvbackend(bpContext *ctx, char *cmd, POOL_MEM &buf, bool any) { // handle header - int32_t length = handle_read_header(ctx, cmd); - if (length < 0) + int32_t length = handle_read_header(ctx, cmd, any); + if (length < 0) { return -1; + } // handle data payload - if (length > 0) - { + if (length > 0) { // check requested buffer size buf.check_size(length + 1); return handle_payload(ctx, buf.c_str(), length); @@ -541,16 +547,17 @@ int32_t PTCOMM::recvbackend(bpContext *ctx, char cmd, POOL_MEM &buf) int32_t PTCOMM::recvbackend_fixed(bpContext *ctx, char cmd, char *buf, int32_t bufsize) { int32_t length = remaininglen; + char lcmd = cmd; - if (!f_cont){ + if (!f_cont) { // handle header - length = handle_read_header(ctx, cmd); + length = handle_read_header(ctx, &lcmd); if (length < 0) return -1; } // handle data payload - if (length > 0){ + if (length > 0) { // we will need subsequent call to handle remaining data only when `buf` to short f_cont = length > bufsize; int32_t nbytes = f_cont * bufsize + (!f_cont) * length; @@ -666,10 +673,11 @@ int32_t PTCOMM::sendbackend(bpContext *ctx, char cmd, POOLMEM *buf, int32_t len) */ int32_t PTCOMM::read_command(bpContext *ctx, POOL_MEM &buf) { - int32_t status = recvbackend(ctx, 'C', buf); - if (status > 0) - { + char cmd = 'C'; + int32_t status = recvbackend(ctx, &cmd, buf, false); + if (status > 0) { /* mark end of string because every command is a string */ + buf.check_size(status + 1); buf.c_str()[status] = '\0'; /* strip any junk in command like '\n' or trailing spaces */ strip_trailing_junk(buf.c_str()); @@ -678,6 +686,34 @@ int32_t PTCOMM::read_command(bpContext *ctx, POOL_MEM &buf) return status; } +/** + * @brief Reads the next packet from the backend communication channel. + * + * It accepts any command or data packet. The next byte after + * the received data will be terminated with '\0' for easy string + * handling. + * + * @param ctx bpContext - for Bacula debug and jobinfo messages + * @param cmd a pointer to a `char` which show what kind of packet was received + * @param buf buffer allocated for command + * @return int32_t + * -1 - when encountered any error + * 0 - when backend sent signal, i.e. EOD or Term + * - the number of bytes received, success + */ +int32_t PTCOMM::read_any(bpContext *ctx, char *cmd, POOL_MEM &buf) +{ + int32_t status = recvbackend(ctx, cmd, buf, true); + if (status > 0) { + /* mark end of string for easy usage */ + buf.check_size(status + 1); + buf.c_str()[status] = '\0'; + status++; + } + + return status; +} + /* * Reads the next data message from the backend. * The number of bytes received will not exceed the buffer length even when @@ -697,11 +733,12 @@ int32_t PTCOMM::read_command(bpContext *ctx, POOL_MEM &buf) int32_t PTCOMM::read_data(bpContext *ctx, POOL_MEM &buf) { int32_t status; + char cmd = 'D'; - if (extpipe > 0){ + if (extpipe > 0) { status = read(extpipe, buf.c_str(), buf.size()); } else { - status = recvbackend(ctx, 'D', buf); + status = recvbackend(ctx, &cmd, buf, false); } return status; @@ -748,9 +785,9 @@ int32_t PTCOMM::read_data_fixed(bpContext *ctx, char *buf, int32_t len) bool PTCOMM::read_ack(bpContext *ctx) { POOL_MEM buf(PM_FNAME); + char cmd = 'F'; - if (recvbackend(ctx, 'F', buf) == 0 && f_eod) - { + if (recvbackend(ctx, &cmd, buf, false) == 0 && f_eod) { f_eod = false; return true; } diff --git a/bacula/src/plugins/fd/pluginlib/ptcomm.h b/bacula/src/plugins/fd/pluginlib/ptcomm.h index 2eb28175f..0176c0347 100644 --- a/bacula/src/plugins/fd/pluginlib/ptcomm.h +++ b/bacula/src/plugins/fd/pluginlib/ptcomm.h @@ -89,11 +89,11 @@ protected: bool recvbackend_data(bpContext *ctx, char *buf, int32_t nbytes); bool sendbackend_data(bpContext *ctx, char *buf, int32_t nbytes); - int32_t recvbackend_header(bpContext *ctx, char cmd); - int32_t handle_read_header(bpContext *ctx, char cmd); + int32_t recvbackend_header(bpContext *ctx, char *cmd, bool any=false); + int32_t handle_read_header(bpContext *ctx, char *cmd, bool any=false); int32_t handle_payload(bpContext *ctx, char *buf, int32_t nbytes); - int32_t recvbackend(bpContext *ctx, char cmd, POOL_MEM &buf); + int32_t recvbackend(bpContext *ctx, char *cmd, POOL_MEM &buf, bool any=false); int32_t recvbackend_fixed(bpContext *ctx, char cmd, char *buf, int32_t bufsize); int32_t sendbackend(bpContext *ctx, char cmd, POOLMEM *buf, int32_t len); @@ -124,6 +124,7 @@ public: bool handshake(bpContext *ctx, const char *pluginname, const char *pluginapi); int32_t read_command(bpContext *ctx, POOL_MEM &buf); + int32_t read_any(bpContext *ctx, char *cmd, POOL_MEM &buf); int32_t read_data(bpContext *ctx, POOL_MEM &buf); int32_t read_data_fixed(bpContext *ctx, char *buf, int32_t len); diff --git a/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c b/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c index f447f4fb1..d6e1a3bf7 100644 --- a/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c +++ b/bacula/src/plugins/fd/pluginlib/test_metaplugin_backend.c @@ -830,19 +830,80 @@ void perform_listing(char *listing){ signal_eod(); } +const unsigned char m_json[] = { + 0x7b, 0x22, 0x77, 0x69, 0x64, 0x67, 0x65, 0x74, 0x22, 0x3a, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x62, 0x75, 0x67, 0x22, + 0x3a, 0x20, 0x22, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 0x3a, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x20, 0x4b, 0x6f, 0x6e, 0x66, 0x61, 0x62, 0x75, 0x6c, 0x61, 0x74, 0x6f, + 0x72, 0x20, 0x57, 0x69, 0x64, 0x67, 0x65, 0x74, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x61, 0x6d, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x77, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x35, + 0x30, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3a, 0x20, 0x35, 0x30, + 0x30, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x20, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x72, + 0x63, 0x22, 0x3a, 0x20, 0x22, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, + 0x53, 0x75, 0x6e, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x3a, 0x20, 0x22, 0x73, 0x75, 0x6e, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x68, 0x4f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x22, 0x3a, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x76, 0x4f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x22, 0x3a, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3a, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x61, + 0x74, 0x61, 0x22, 0x3a, 0x20, 0x22, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x20, + 0x48, 0x65, 0x72, 0x65, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x3a, 0x20, 0x33, + 0x36, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x62, 0x6f, 0x6c, + 0x64, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x74, 0x65, 0x78, + 0x74, 0x31, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x68, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x3a, 0x20, + 0x32, 0x35, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x76, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x3a, 0x20, + 0x31, 0x30, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x22, + 0x3a, 0x20, 0x22, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x6e, 0x4d, + 0x6f, 0x75, 0x73, 0x65, 0x55, 0x70, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x75, + 0x6e, 0x31, 0x2e, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x20, 0x3d, + 0x20, 0x28, 0x73, 0x75, 0x6e, 0x31, 0x2e, 0x6f, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x20, 0x2f, 0x20, 0x31, 0x30, 0x30, 0x29, 0x20, 0x2a, 0x20, + 0x39, 0x30, 0x3b, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, + 0x7d, 0x0a, 0x00 +}; +unsigned int m_json_len = 603; + /* * The query param procedure * return 3 simple parameters */ -void perform_queryparam(char *query) +void perform_queryparam(const char *query) { /* Query Loop (5) */ - snprintf(buf, BIGBUFLEN, "%s=test1\n", query); - write_plugin('C', buf); - snprintf(buf, BIGBUFLEN, "%s=test2\n", query); - write_plugin('C', buf); - snprintf(buf, BIGBUFLEN, "%s=test3\n", query); - write_plugin('C', buf); + if (strcmp(query, "m_id") == 0) { + snprintf(buf, BIGBUFLEN, "%s=test1\n", query); + write_plugin('C', buf); + snprintf(buf, BIGBUFLEN, "%s=test2\n", query); + write_plugin('C', buf); + snprintf(buf, BIGBUFLEN, "%s=test3\n", query); + write_plugin('C', buf); + } else + if (strcmp(query, "m_json") == 0) { + write_plugin_bin((const char*)m_json, m_json_len); + write_plugin('D', "UmFkb3PFgmF3IEtvcnplbmlld3NraQo=\n"); + } /* this is the end of all data */ signal_eod(); diff --git a/regress/scripts/metaplugin-protocol-tests.sh b/regress/scripts/metaplugin-protocol-tests.sh index 4925d6173..e91b1a7c1 100755 --- a/regress/scripts/metaplugin-protocol-tests.sh +++ b/regress/scripts/metaplugin-protocol-tests.sh @@ -367,6 +367,22 @@ END_OF_DATA run_bconsole TEST=$((TEST+1)) +cat <${cwd}/tmp/bconcmds +@# +@# Query +@# +@output /dev/null +messages +@$out ${cwd}/tmp/qlog${TEST}.out +setdebug level=500 client=$CLIENT trace=1 +.query client=$CLIENT plugin="$Plugin" parameter="m_json" +messages +@output +quit +END_OF_DATA +run_bconsole +TEST=$((TEST+1)) + stop_bacula RET=$(grep "jobstatus:" ${cwd}/tmp/log1.out | awk '{print $2}') @@ -535,4 +551,12 @@ then estat=3 fi +JSON=$(grep -c "widget" ${cwd}/tmp/qlog3.out) +BASE=$(grep -c "UmFkb3PFgmF3IEtvcnplbmlld3NraQo=" ${cwd}/tmp/qlog3.out) +if [ "$JSON" -ne 1 ] || [ "$BASE" -ne 1 ] +then + echo "qlog3" "$JSON" "$BASE" + estat=4 +fi + end_test