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

Reply via email to