]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add list joblog pattern= option
authorEric Bollengier <eric@baculasystems.com>
Wed, 23 Mar 2022 18:02:39 +0000 (19:02 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:56:58 +0000 (13:56 +0200)
bacula/src/cats/bdb.h
bacula/src/cats/bdb_mysql.h
bacula/src/cats/bdb_postgresql.h
bacula/src/cats/mysql.c
bacula/src/cats/postgresql.c
bacula/src/cats/protos.h
bacula/src/cats/sql_list.c
bacula/src/cats/sqlite.c
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_output.c

index 8357f42a3cbc9869d2c1c572880b63c8f20f6dbe..12f9c6b58bf991ed8b6f36c7296068e679cb1ad3 100644 (file)
@@ -275,7 +275,7 @@ public:
    void bdb_list_media_records(JCR *jcr, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
    void bdb_list_jobmedia_records(JCR *jcr, JobId_t JobId, char *volume, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
    void bdb_list_filemedia_records(JCR *jcr, JobId_t JobId, uint32_t FileIndex, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
-   void bdb_list_joblog_records(JCR *jcr, JobId_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
+   void bdb_list_joblog_records(JCR *jcr, JobId_t JobId, const char *pattern, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
    int  bdb_list_sql_query(JCR *jcr, const char *title, const char *query, DB_LIST_HANDLER *sendit, void *ctx, int verbose, e_list_type type);
    void bdb_list_client_records(JCR *jcr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
    void bdb_list_copies_records(JCR *jcr, uint32_t limit, char *jobids, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
@@ -307,7 +307,7 @@ public:
    bool bdb_update_snapshot_record(JCR *jcr, SNAPSHOT_DBR *sr);
 
    /* Pure virtual low level methods */
-   virtual void bdb_escape_string(JCR *jcr, char *snew, char *old, int len) = 0;
+   virtual void bdb_escape_string(JCR *jcr, char *snew, const char *old, int len) = 0;
    virtual char *bdb_escape_object(JCR *jcr, char *old, int len) = 0;
    virtual void bdb_unescape_object(JCR *jcr, char *from, int32_t expected_len,
                    POOLMEM **dest, int32_t *len) = 0;
index 6d14df5b2e0442430ae597e5222076fe9f487e3b..cab3d0d3c97b318947c235424368401a08372745 100644 (file)
@@ -46,7 +46,7 @@ public:
    bool bdb_open_database(JCR *jcr);
    void bdb_close_database(JCR *jcr);
    void bdb_thread_cleanup(void);
-   void bdb_escape_string(JCR *jcr, char *snew, char *old, int len);
+   void bdb_escape_string(JCR *jcr, char *snew, const char *old, int len);
    char *bdb_escape_object(JCR *jcr, char *old, int len);
    void bdb_unescape_object(JCR *jcr, char *from, int32_t expected_len,
                            POOLMEM **dest, int32_t *len);
index b4b3599de81d1c87af5638df78a9e4083cb7aac4..e379b7435452fb549c616c7ea7da29178d014919 100644 (file)
@@ -35,7 +35,7 @@ public:
    bool bdb_open_database(JCR *jcr);
    void bdb_close_database(JCR *jcr);
    void bdb_thread_cleanup(void);
-   void bdb_escape_string(JCR *jcr, char *snew, char *old, int len);
+   void bdb_escape_string(JCR *jcr, char *snew, const char *old, int len);
    char *bdb_escape_object(JCR *jcr, char *old, int len);
    void bdb_unescape_object(JCR *jcr, char *from, int32_t expected_len,
                            POOLMEM **dest, int32_t *len);
index 7fa13ff7e05089ffe0a88cd84fa7d0c0a7c117f5..eccc13bbc5a60b76817e5a7766d6a638ff27d36d 100644 (file)
@@ -441,7 +441,7 @@ void BDB_MYSQL::bdb_thread_cleanup(void)
  *   string must be long enough (max 2*old+1) to hold 
  *   the escaped output. 
  */ 
-void BDB_MYSQL::bdb_escape_string(JCR *jcr, char *snew, char *old, int len) 
+void BDB_MYSQL::bdb_escape_string(JCR *jcr, char *snew, const char *old, int len) 
 { 
    BDB_MYSQL *mdb = this; 
    mysql_real_escape_string(mdb->m_db_handle, snew, old, len); 
index 74b15f01ea2e1d068a6a4d35afefc2d790126690..b369a325612778316ee06086e420026905f185cb 100644 (file)
@@ -566,7 +566,7 @@ void BDB_POSTGRESQL::bdb_thread_cleanup(void)
  *    string must be long enough (max 2*old+1) to hold
  *    the escaped output.
  */
-void BDB_POSTGRESQL::bdb_escape_string(JCR *jcr, char *snew, char *old, int len)
+void BDB_POSTGRESQL::bdb_escape_string(JCR *jcr, char *snew, const char *old, int len)
 {
    BDB_POSTGRESQL *mdb = this;
    int failed; 
index 890e69b3a38787c45ef8e0adc317fafc771652d4..006324799b6513bc45cd908cbd4eff642303752a 100644 (file)
@@ -292,8 +292,8 @@ void bdb_free_restoreobject_record(JCR *jcr, ROBJECT_DBR *rr);
            mdb->bdb_list_jobmedia_records(jcr, JobId, volume, sendit, ctx, type)
 #define db_list_filemedia_records(jcr, mdb, JobId, FI, sendit, ctx, type) \
            mdb->bdb_list_filemedia_records(jcr, JobId, FI, sendit, ctx, type)
-#define db_list_joblog_records(jcr, mdb, JobId, sendit, ctx, type)      \
-           mdb->bdb_list_joblog_records(jcr, JobId, sendit, ctx, type)
+#define db_list_joblog_records(jcr, mdb, JobId, pattern, sendit, ctx, type) \
+   mdb->bdb_list_joblog_records(jcr, JobId, pattern, sendit, ctx, type)
 #define db_list_sql_query(jcr, mdb, title, query, sendit, ctx, verbose, type) \
            mdb->bdb_list_sql_query(jcr, title, query, sendit, ctx, verbose, type)
 #define db_list_client_records(jcr, mdb, sendit, ctx, type) \
index 2fa7b33cfff957d21c662964e7df3bad3e7f32d4..45f7f917061bba0758a97e1771ec743f1ad5f400 100644 (file)
@@ -791,36 +791,57 @@ bail_out:
    bdb_unlock();
 }
 
-void BDB::bdb_list_joblog_records(JCR *jcr, uint32_t JobId,
+void BDB::bdb_list_joblog_records(JCR *jcr, uint32_t JobId, const char *pattern,
                               DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
 {
-   char ed1[50];
-   if (JobId <= 0) {
+   if (JobId <= 0 && !pattern) {
       return;
    }
+
+   POOL_MEM tmp, where2;
+   char ed1[50];
    bdb_lock();
 
+   if (JobId > 0) {
+      Mmsg(tmp, "Log.JobId=%s", edit_int64(JobId, ed1));
+      append_filter(where2.handle(), tmp.c_str());
+   }
+   
+   if (pattern) {
+      POOL_MEM esc;
+      esc.check_size(strlen(pattern) * 2 + 1);
+      bdb_escape_string(jcr, esc.c_str(), pattern, strlen(pattern));
+      Mmsg(tmp, "Log.LogText ILIKE '%%%s%%' ", esc.c_str());
+      append_filter(where2.handle(), tmp.c_str());
+   }
+
    const char *where = get_acls(DB_ACL_BIT(DB_ACL_JOB)     |
                                 DB_ACL_BIT(DB_ACL_FILESET) |
-                                DB_ACL_BIT(DB_ACL_CLIENT), false);
+                                DB_ACL_BIT(DB_ACL_CLIENT), where2.c_str()[0] == '\0');
 
    const char *join = *where ? get_acl_join_filter(DB_ACL_BIT(DB_ACL_JOB)     |
                                                    DB_ACL_BIT(DB_ACL_FILESET) |
                                                    DB_ACL_BIT(DB_ACL_CLIENT)) : "";
-
-   if (type == VERT_LIST || type == JSON_LIST) {
+   
+   if (type == VERT_LIST) {
       Mmsg(cmd, "SELECT Time,LogText FROM Log %s "
-           "WHERE Log.JobId=%s %s ORDER BY LogId ASC",
+           "%s %s ORDER BY LogId ASC",
            join,
-           edit_int64(JobId, ed1),
+           where2.c_str(),
+           where);
+
+   } else if (type == JSON_LIST) {
+      Mmsg(cmd, "SELECT JobId, Time,LogText FROM Log %s "
+           "%s %s ORDER BY LogId ASC",
+           join,
+           where2.c_str(),
            where);
 
    } else {
       Mmsg(cmd, "SELECT LogText FROM Log %s "
-           "WHERE Log.JobId=%s %s ORDER BY LogId ASC",
+           "%s %s ORDER BY LogId ASC",
            join,
-           edit_int64(JobId, ed1),
+           where2.c_str(),
            where);
    }
    Dmsg1(DT_SQL|50, "q=%s\n", cmd);
index 91250a384e8d078fb29efc9b5fa005b9873787d2..0fa5205195f4359a46499c340a89b430d4f84172 100644 (file)
@@ -318,7 +318,7 @@ void BDB_SQLITE::bdb_thread_cleanup(void)
  *   string must be long enough (max 2*old+1) to hold 
  *   the escaped output. 
  */ 
-void BDB_SQLITE::bdb_escape_string(JCR *jcr, char *snew, char *sold, int len) 
+void BDB_SQLITE::bdb_escape_string(JCR *jcr, char *snew, const char *sold, int len) 
 {  
    char *n, *o; 
  
index e790cebe78c139562da1ec87bfda6c4063d183c0..fd545a466610f7167e5e7bf6734bb0236934aacc 100644 (file)
@@ -133,7 +133,7 @@ static struct cmdstruct commands[] = {                                      /* C
  { NT_("list"),       list_cmd,      _("List objects from catalog"),
    NT_("jobs [client=<cli>] [jobid=<nn>] [ujobid=<name>] [job=<name>] [tag=<name>] [joberrors] [jobstatus=<s>] [level=<l>] [jobtype=<t>] [days=<n>] [hours=<n>] [limit=<n>] [order=<asc|desc>]|\n"
        "\tjobtotals | pools | volume | media <pool=pool-name> | files [type=<deleted|all>] jobid=<nn> | copies jobid=<nn> |\n"
-       "\tjoblog jobid=<nn> | pluginrestoreconf jobid=<nn> restoreobjectid=<nn> | snapshot | \n"
+       "\tjoblog [pattern=<str>] jobid=<nn> | pluginrestoreconf jobid=<nn> restoreobjectid=<nn> | snapshot | \n"
        "\tfilemedia jobid=<nn> fileindex=<mm> | clients | jobmedia [jobid=<nn> volume=<s>] |\n"
        "\tevents [type=<str> | limit=<int> | order=<asc|desc> | days=<int> | start=<time-specification> | end=<time-specification> |\n"
        "\t\t source=<str> | code=<str> | type=<str> ]\n"
index 133e09461c6bd6755bf64b9cc9cb7cf8262b45f5..cc6a34b35d590ecb16e136183029f4c1da010c22 100644 (file)
@@ -321,7 +321,8 @@ bail_out:
  *  list jobname=name   - same as above
  *  list jobmedia jobid=<nn>
  *  list jobmedia job=name
- *  list joblog jobid=<nn>
+ *  list joblog pattern=xxx jobid=<nn> 
+ *  list joblog pattern=xxx jobid=<nn> 
  *  list joblog job=name
  *  list files [type=<deleted|all>] jobid=<nn> - list files saved for job nn
  *  list files [type=<deleted|all>] job=name
@@ -619,26 +620,32 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
       /* List JOBLOG */
       } else if (strcasecmp(ua->argk[i], NT_("joblog")) == 0) {
          bool done = false;
+         const char *pattern=NULL;
          for (j=i+1; j<ua->argc; j++) {
             if (strcasecmp(ua->argk[j], NT_("ujobid")) == 0 && ua->argv[j]) {
                bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
                jr.JobId = 0;
                db_get_job_record(ua->jcr, ua->db, &jr);
                jobid = jr.JobId;
+
             } else if (strcasecmp(ua->argk[j], NT_("jobid")) == 0 && ua->argv[j]) {
                jobid = str_to_int64(ua->argv[j]);
+
+            } else if (strcasecmp(ua->argk[j], NT_("pattern")) == 0 && ua->argv[j]) {
+               pattern = ua->argv[j];
+               continue;
+
             } else {
                continue;
             }
-            db_list_joblog_records(ua->jcr, ua->db, jobid, prtit, ua, llist);
+            db_list_joblog_records(ua->jcr, ua->db, jobid, pattern, prtit, ua, llist);
             done = true;
          }
          if (!done) {
             /* List for all jobs (jobid=0) */
-            db_list_joblog_records(ua->jcr, ua->db, 0, prtit, ua, llist);
+            db_list_joblog_records(ua->jcr, ua->db, 0, pattern, prtit, ua, llist);
          }
 
-
       /* List POOLS */
       } else if (strcasecmp(ua->argk[i], NT_("pool")) == 0 ||
                  strcasecmp(ua->argk[i], NT_("pools")) == 0) {
@@ -1098,6 +1105,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
                  || strcasecmp(ua->argk[i], NT_("daemon")) == 0
                  || strcasecmp(ua->argk[i], NT_("code")) == 0
                  || strcasecmp(ua->argk[i], NT_("offset")) == 0
+                 || strcasecmp(ua->argk[i], NT_("pattern")) == 0
          ) {
          /* Ignore it */
       } else if (strcasecmp(ua->argk[i], NT_("snapshot")) == 0 ||