]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add Tenant resource
authorEric Bollengier <eric@baculasystems.com>
Fri, 16 Sep 2022 08:09:39 +0000 (10:09 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:56:59 +0000 (13:56 +0200)
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/next_vol.c

index 0b610a8a7b0f5607b3ff9b2efee2c990e820e101..1d4b0534b8e055acc111276f8775ebf4984a71dd 100644 (file)
@@ -409,6 +409,23 @@ static RES_ITEM dir_items[] = {
    {NULL, NULL, {0}, 0, 0, 0}
 };
 
+/*
+ *    Console Resource
+ *
+ *   name          handler     value                 code flags    default_value
+ */
+static RES_ITEM tenant_items[] = {
+   {"Name",        store_name,     ITEM(res_tenant.hdr.name), 0, ITEM_REQUIRED, 0},
+   {"Description", store_str,      ITEM(res_tenant.hdr.desc), 0, 0, 0},
+   {"MaximumVolumeBytes", store_size64, ITEM(res_tenant.MaxVolBytes), 0, 0, 0},
+   {"MaximumClients", store_int32, ITEM(res_tenant.MaxClients), 0, 0, 0},
+   {"WarningVolumeBytes", store_size64, ITEM(res_tenant.WarnVolBytes), 0, 0, 0},
+   {"MaximumJobs", store_int32, ITEM(res_tenant.MaxJobs), 0, 0, 0},
+   {"MaximumStorages", store_int32, ITEM(res_tenant.MaxStorages), 0, 0, 0},
+   {"Isolated", store_bool, ITEM(res_tenant.Isolated), 0, 0, 0},
+   {"Enabled",     store_bool, ITEM(res_tenant.Enabled), 0, ITEM_DEFAULT, true},
+   {NULL, NULL, {0}, 0, 0, 0}
+};
 /*
  *    Console Resource
  *
@@ -802,6 +819,7 @@ RES_TABLE resources[] = {
    {"Console",       con_items,        R_CONSOLE},
    {"JobDefs",       job_items,        R_JOBDEFS},
    {"Statistics",    collector_items,  R_COLLECTOR},
+   {"Tenant",        tenant_items,     R_TENANT},
    {"Device",        NULL,             R_DEVICE},  /* info obtained from SD */
    {"Autochanger",   store_items,      R_AUTOCHANGER},  /* alias for R_STORAGE */
    {NULL,            NULL,             0}
@@ -953,6 +971,11 @@ void dump_resource(int type, RES *ares, void sendit(void *sock, const char *fmt,
       recurse = false;
    }
    switch (type) {
+   case R_TENANT:
+      sendit(sock, _("Tenant: name=%s MaxJobs=%d MaxClients=%d MaxVolBytes=%lld Enabled=%d\n"),
+             ares->name, res->res_tenant.MaxJobs, res->res_tenant.MaxClients,
+             res->res_tenant.MaxVolBytes, res->res_tenant.Enabled);
+      break;
    case R_DIRECTOR:
       sendit(sock, _("Director: name=%s MaxJobs=%d FDtimeout=%s SDtimeout=%s AutoPrune=%d\n"),
          ares->name, res->res_dir.MaxConcurrentJobs,
@@ -1658,6 +1681,7 @@ void free_resource(RES *rres, int type)
          free(res->res_dir.customerid);
       }
       break;
+   case R_TENANT:
    case R_DEVICE:
    case R_COUNTER:
        break;
@@ -1937,6 +1961,9 @@ int get_resource_size(int type)
     * The following code is only executed during pass 1
     */
    switch (type) {
+   case R_TENANT:
+      size = sizeof(TENANT);
+      break;
    case R_DIRECTOR:
       size = sizeof(DIRRES);
       break;
@@ -2042,6 +2069,7 @@ bool save_resource(CONFIG *config, int type, RES_ITEM *items, int pass)
       case R_MSGS:
       case R_FILESET:
       case R_DEVICE:
+      case R_TENANT:
          break;
 
       /*
@@ -2084,7 +2112,7 @@ bool save_resource(CONFIG *config, int type, RES_ITEM *items, int pass)
          type = R_STORAGE;         /* force Storage type */
          if ((res = (URES *)GetResWithName(type, res_all.res_store.hdr.name)) == NULL) {
             Mmsg(config->m_errmsg, _("Cannot find Storage resource %s\n"),
-                 res_all.res_dir.hdr.name);
+                 res_all.res_store.hdr.name);
             return false;
          }
          /* we must explicitly copy the device alist pointer */
@@ -2103,9 +2131,9 @@ bool save_resource(CONFIG *config, int type, RES_ITEM *items, int pass)
          break;
       case R_JOB:
       case R_JOBDEFS:
-         if ((res = (URES *)GetResWithName(type, res_all.res_dir.hdr.name)) == NULL) {
+         if ((res = (URES *)GetResWithName(type, res_all.res_job.hdr.name)) == NULL) {
             Mmsg(config->m_errmsg, _("Cannot find Job resource %s\n"),
-                 res_all.res_dir.hdr.name);
+                 res_all.res_job.hdr.name);
             return false;
          }
          res->res_job.messages   = res_all.res_job.messages;
index 07f29d31a4c693dcef7a86558ff84e67f68bd08e..e70edde5c729bdff5f844b8c8b63670901c21d3c 100644 (file)
@@ -42,6 +42,7 @@ enum {
    R_CONSOLE,
    R_JOBDEFS,
    R_COLLECTOR,
+   R_TENANT,
    R_DEVICE,       /* This is the real last device class */
 
    R_AUTOCHANGER,  /* Alias for R_STORAGE after R_LAST */
@@ -84,6 +85,7 @@ class RUN;
 class DEVICE;
 class RUNSCRIPT;
 class CAT;
+class TENANT;
 
 /*
  *   Director Resource
@@ -719,12 +721,32 @@ public:
 
 inline char *POOL::name() const { return hdr.name; }
 
+/*
+ *    Tenant Resource
+ */
+class TENANT {
+public:
+   RES   hdr;
+   int32_t MaxClients;         /* Maximum clients allowed */
+   uint64_t MaxVolBytes;       /* Maximum bytes allowed */
+   uint64_t WarnVolBytes;      /* Print warnings after X bytes */
+   int32_t MaxJobs;            /* Maximum job resources allowed */
+   int32_t MaxStorages;        /* Maximum Storage resources allowed */
+   int32_t Isolated;           /* Subtenants can have visibility among them */
+   int32_t Enabled;            /* Enabled or not */
+   /* Methods */
+   char *name() const;
+};
+
+inline char *TENANT::name() const { return hdr.name; }
+
 
 /* Define the Union of all the above
  * resource structure definitions.
  */
 union URES {
    DIRRES     res_dir;
+   TENANT     res_tenant;
    CONRES     res_con;
    CLIENT     res_client;
    STORE      res_store;
@@ -775,6 +797,7 @@ public:
    void clearall();
 };
 
+
 #define GetPoolResWithName(x) ((POOL *)GetResWithName(R_POOL, (x)))
 #define GetStoreResWithName(x) ((STORE *)GetResWithName(R_STORAGE, (x)))
 #define GetSchedResWithName(x) ((SCHED *)GetResWithName(R_SCHEDULE, (x)))
index 770fa76644317267fa19924b7d8377236834fca8..d38e9c1b1db655eccd35e3aba50f3d68a2639011 100644 (file)
@@ -324,7 +324,9 @@ bool has_volume_expired(JCR *jcr, MEDIA_DBR *mr)
          expired = true;
       }
    }
-
+   /* Here, if the volume is WORM, we cannot change the status if a storage
+    * is not connected
+    */
    if (expired) {
       /* Need to update media */
       Dmsg1(dbglvl, "Vol=%s has expired update media record\n", mr->VolumeName);