]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Fix #7448 About extending 'list jobs' with hours and days parameters
authorMichal Rakowski <michal.rakowski@baculasystems.com>
Wed, 14 Apr 2021 17:01:08 +0000 (19:01 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:03:01 +0000 (09:03 +0100)
bacula/src/cats/cats.h
bacula/src/cats/sql_list.c
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_output.c

index e9998c73d55722faefa29a89c2070dd578562c52..fa26e47d54285a04f3533d52aaa8566cf9120810 100644 (file)
@@ -168,6 +168,8 @@ struct JOB_DBR {
    faddr_t rec_addr;
    int32_t FileIndex;                 /* added during Verify */
 
+   char FromDate[MAX_TIME_LENGTH];    /* Used for filtering job records ('days' and 'hours' in list cmd) */
+
    int     CorrNbJob;                 /* used by dbd_get_job_statistics() */
    int     CorrJobBytes;              /* used by dbd_get_job_statistics() */
    int     CorrJobFiles;              /* used by dbd_get_job_statistics() */
index 37172d2c569dde54e8abb4e7e90726130cb309c7..878c516d0734abec727f46d5518a2f4f60873531 100644 (file)
@@ -760,6 +760,12 @@ alist *BDB::bdb_list_job_records(JCR *jcr, JOB_DBR *jr, DB_LIST_HANDLER *sendit,
       append_filter(&where, tmp);
    }
 
+   if (jr->FromDate[0]) {
+      bdb_escape_string(jcr, esc, jr->FromDate, strlen(jr->FromDate));
+      Mmsg(tmp, " Job.StartTime >= '%s' ", esc);
+      append_filter(&where, tmp);
+   }
+
    where_tmp = get_acls(DB_ACL_BIT(DB_ACL_CLIENT)  |
                         DB_ACL_BIT(DB_ACL_JOB)     |
                         DB_ACL_BIT(DB_ACL_FILESET),
index 083ec405ae0d82d952e8b1538434020ba776c949..bd1523988a8848f59e701761a263932f74bb66c7 100644 (file)
@@ -131,7 +131,7 @@ static struct cmdstruct commands[] = {                                      /* C
 
  { NT_("label"),      label_cmd,     _("Label a tape"), NT_("storage=<storage> volume=<vol> pool=<pool> slot=<slot> drive=<nb> barcodes [yes]"), false},
  { 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>] [limit=<n>] [order=<asc|desc>]|\n"
+   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"
        "\tfilemedia jobid=<nn> fileindex=<mm> | clients\n"
index 8305687a05004c6110440ac917f6155b84b95d9e..2a918d954b6f56587d421afc0b72f550d281e767 100644 (file)
@@ -355,6 +355,27 @@ int list_cmd(UAContext *ua, const char *cmd)
    }
 }
 
+/* Simple helper to setup date used for filtering records.
+ * Value can be passed as a days or hours count */
+static bool setup_start_date(const char *val, bool days, char *dest, uint32_t dest_len)
+{
+   time_t stime;
+   struct tm tm;
+   int hours_count;
+
+   if (!is_an_integer(val)) {
+      return false;
+   }
+
+   /* Do we have hours or days count */
+   hours_count = days ? 24 : 1;
+   stime = time(NULL) - atoi(val) * hours_count * 60*60;
+   (void)localtime_r(&stime, &tm);
+   strftime(dest, dest_len, "%Y-%m-%d %H:%M:%S", &tm);
+
+   return true;
+}
+
 static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
 {
    POOLMEM *VolumeName;
@@ -422,6 +443,16 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
                jr.ClientId = cr.ClientId;
             }
          }
+      } else if (strcasecmp(ua->argk[j], NT_("days")) == 0 && ua->argv[j]) {
+         if (!setup_start_date(ua->argv[j], true, jr.FromDate, sizeof(jr.FromDate))) {
+            ua->error_msg(_("Expected integer passed as a days count, got: %s\n"), ua->argv[j]);
+            return 1;
+         }
+      } else if (strcasecmp(ua->argk[j], NT_("hours")) == 0 && ua->argv[j]) {
+         if (!setup_start_date(ua->argv[j], false, jr.FromDate, sizeof(jr.FromDate))) {
+            ua->error_msg(_("Expected integer passed as a hours count, got: %s\n"), ua->argv[j]);
+            return 1;
+         }
       }
    }
 
@@ -818,8 +849,6 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
 
       } else if (strcasecmp(ua->argk[i], NT_("events")) == 0) {
          EVENTS_DBR event;
-         time_t stime;
-         struct tm tm;
 
          for (j=i+1; j<ua->argc; j++) {
             if (strcasecmp(ua->argk[j], NT_("type")) == 0 && ua->argv[j]) {
@@ -833,10 +862,15 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
                event.order = bstrcasecmp(ua->argv[j], "DESC") == 0;
 
             } else if (strcasecmp(ua->argk[j], NT_("days")) == 0 && ua->argv[j]) {
-               stime = time(NULL) - atoi(ua->argv[j]) * 24*60*60;
-               (void)localtime_r(&stime, &tm);
-               strftime(event.start, sizeof(event.start), "%Y-%m-%d %H:%M:%S", &tm);
-
+               if (!setup_start_date(ua->argv[j], true, event.start, sizeof(event.start))) {
+                  ua->error_msg(_("Expected integer passed as a days count, got: %s\n"), ua->argv[j]);
+                  return 1;
+               }
+            } else if (strcasecmp(ua->argk[j], NT_("hours")) == 0 && ua->argv[j]) {
+               if (!setup_start_date(ua->argv[j], false, event.start, sizeof(event.start))) {
+                  ua->error_msg(_("Expected integer passed as a hours count, got: %s\n"), ua->argv[j]);
+                  return 1;
+               }
             } else if (strcasecmp(ua->argk[j], NT_("start")) == 0 && ua->argv[j]) {
                bstrncpy(event.start, ua->argv[j], sizeof(event.start)); /* TODO: check format */
 
@@ -860,6 +894,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
 
       } else if (strcasecmp(ua->argk[i], NT_("limit")) == 0
                  || strcasecmp(ua->argk[i], NT_("days")) == 0
+                 || strcasecmp(ua->argk[i], NT_("hours")) == 0
                  || strcasecmp(ua->argk[i], NT_("joberrors")) == 0
                  || strcasecmp(ua->argk[i], NT_("order")) == 0
                  || strcasecmp(ua->argk[i], NT_("jobstatus")) == 0