It's been a while that I already started to write a small script to help
me and a customer to improve our weekly change of tapes:
they use a small tape library with 8 slots, with their schedule etc we
roughly change tapes each week or so.
To choose the tapes to remove and which ones to supply I look at bacularis.
The default "algorithm" is something like:
- look at the Volumes for the default Pool "Daily"
- sort them by LastWritten
- only the Enabled ones.
- Retentiontime over
- Status Full, Recycle, Append ...
- not in changer
I do that "manually" by looking and filtering in my head more or less ;-)
Now I'd like to give it another try and wrap that into a python script.
There should be a cronjob that tells us which tapes to remove from and
which to put into the changer (for the standard schedule).
Do you guys see something missing in my approach above?
With a bit of LLM I came up with this so far:
--- code ---
#!/usr/bin/env python3
import psycopg2
import sys
from datetime import datetime, timedelta
DB_CONFIG = {
"host": "localhost",
"dbname": "bacula",
"user": "bacula",
"password": "somepass"
}
POOL_NAME = "Daily"
USABLE_STATUS = ("Append", "Recycle", "Full")
RETENTION_DAYS = 30
QUERY = """
SELECT
m.mediaid,
m.volumename,
m.volstatus,
m.lastwritten,
m.inchanger
FROM media m
JOIN pool p ON m.poolid = p.poolid
WHERE
p.name = %s
AND m.volstatus IN %s
AND m.lastwritten IS NOT NULL
ORDER BY
m.lastwritten,
m.mediaid
LIMIT 8;
"""
def main():
# Verbindung zur DB herstellen
conn = psycopg2.connect(**DB_CONFIG)
cur = conn.cursor()
# Abfrage ausführen
cur.execute(QUERY, (POOL_NAME, USABLE_STATUS))
rows = cur.fetchall()
if not rows:
print(f"CRITICAL: Keine verwendbaren Tapes im Pool '{POOL_NAME}'")
sys.exit(2)
print(f"Nächste 8 Tapes mit abgelaufener Retention im Pool
'{POOL_NAME}':\n")
now = datetime.now()
for volid, volume, status, lastwritten, inchanger in rows:
lastwritten_str = lastwritten if lastwritten else "Noch nie verwendet"
if lastwritten:
lastwritten_date = lastwritten
else:
lastwritten_date = datetime.min # Wenn nie benutzt, setze
auf minimalen Wert
expiration_date = lastwritten_date + timedelta(days=RETENTION_DAYS)
if expiration_date <= now:
retention_status = "Abgelaufen"
else:
retention_status = f"Verbleibend: {expiration_date - now}"
# Changer-Status anzeigen
changer_status = "Im Changer" if inchanger else "Nicht im Changer"
# Ausgabe
print(f"{volume:15} {status:8} {lastwritten_str}
{retention_status:30} {changer_status}")
# Verbindung schließen
cur.close()
conn.close()
if __name__ == "__main__":
main()
--- code end ---
(forgive the german parts)
Anyone interested in working on such a script?
Any obvious flaws in my approach?
Thanks, regards, Stefan
_______________________________________________
Bacula-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bacula-users