I can't speak to your query, however here's how I solve the offsite issue. 
I have a separate pool of tapes for offsite backups. I run a full backup to 
that pool every 2 weeks (the interval that I rotate tapes offsite). 

In the defaults for my offsite jobs I have
  RunScript {
    RunsOnClient = no
    RunsWhen = after
    FailJobOnError = yes
    Command  = "/etc/bareos/record-offsite-volume %j %v"
  }

--- record-offsite-volume ---
#!/bin/sh

jobid=$1
volume=$2

printf "${volume}\n" > /etc/bareos/offsite-status/offsite-volume-${jobid} 
|| mail -s "offsite info lost ${volume}" root@localhost
exit 0
-----

My offsite backup catalog runs last due to priority and has
  RunScript {
    RunsOnClient = no
    RunsWhen = After
    FailJobOnError = yes
    Command  = "/etc/bareos/after-offsite %j %v"
  }
 RunScript {
    RunsOnClient = no
    RunsWhen = After
    FailJobOnError = no
    Command = "/etc/bareos/release-drive"
  }

--- release-drive ---
#!/bin/sh

debug() { ! "${log_debug-false}" || log "DEBUG: $*" >&2; }
log() { printf '%s\n' "$*"; }
warn() { log "WARNING: $*" >&2; }
error() { log "ERROR: $*" >&2; }
fatal() { error "$*"; exit 1; }
try() { "$@" || fatal "'$@' failed"; }

mydir=$(cd "$(dirname "$0")" && pwd -L) || fatal "Unable to determine 
script directory"

cleanup() {
    debug "In cleanup"
}
trap 'cleanup' INT TERM EXIT

echo "release storage=PV-124T" | bconsole

-------


--- after-offsite ---
#!/usr/bin/env python

import warnings
with warnings.catch_warnings():
    import re
    import sys
    from optparse import OptionParser
    import subprocess
    import datetime
    import os
    import os.path
    import smtplib
    from email.mime.text import MIMEText

status_dir="/etc/bareos/offsite-status"

def cleanup_files():
    # clean up the files that contain the volume information
    for name in os.listdir(status_dir):
        if name.startswith("offsite-volume-"):
            os.remove(os.path.join(status_dir, name))

def gather_used_volumes():
    volumes={}
    for name in os.listdir(status_dir):
        if name.startswith("offsite-volume-"):
            line = open(os.path.join(status_dir, name)).read().rstrip()
            for volume in line.split("|"):
                volumes[volume] = 1
    return volumes.keys()

def send_message(recipient, subject, message):
    msg = MIMEText(message)
    msg['Subject'] = subject
    msg['From'] = 'root'
    msg['To'] = recipient

    server = smtplib.SMTP('localhost')
    server.sendmail('root', [recipient], msg.as_string())
    server.quit()

def compose_and_send_message(volumes_used):
    message="""
Eject offsite tapes and send to offsite storage
Volumes Used:
%s""" % ("\n".join(volumes_used))
    send_message('root', 'Offsite Tape Rotation', message)

def mark_volume_used(volume):
    subprocess.call("echo 'update volume=%s volstatus=Used' | 
/usr/bin/bconsole" % (volume), shell=True)

def main(argv=None):
    if argv is None:
        argv = sys.argv

    parser = OptionParser()
    (options, args) = parser.parse_args(argv)

    jobid=args[1]
    volume=args[2]

    # record offsite volume first and then send the email about what to do
    subprocess.call("/etc/bareos/record-offsite-volume %s %s" % (jobid, 
volume), shell=True)

    volumes_used = gather_used_volumes()

    # mark all volumes as used
    for volume in volumes_used:
        mark_volume_used(volume)

    compose_and_send_message(volumes_used)
    cleanup_files()



if __name__ == "__main__":
    sys.exit(main())

--------

On Friday, March 11, 2022 at 6:00:08 AM UTC-6 James Youngman wrote:

> I didn't get any replies, but I devised this query:
>
> SELECT DISTINCT media.volumename, media.volstatus, pool.name AS pool,
> media.mediatype, job.name AS job_name, job.starttime
> FROM (
> SELECT job.name as name, MAX(starttime) AS starttime
> FROM job
> WHERE job.level = 'F' AND level='F' AND jobstatus IN ('T', 'W')
> AND job.name != 'BackupCatalog' AND AGE(starttime) < INTERVAL '60 days'
> GROUP BY job.name
> ) AS successful_full_jobs
> JOIN job ON job.name = successful_full_jobs.name AND job.starttime =
> successful_full_jobs.starttime
> JOIN jobmedia ON jobmedia.jobid = job.jobid
> JOIN media ON media.mediaid = jobmedia.mediaid
> JOIN pool ON pool.poolid = media.poolid
> ORDER BY media.volumename;
>
>
> I'm not that familiar with the data model, so this query may be incorrect.
>
> One thing I find unsatisfactory about it is the "AGE(starttime) <
> INTERVAL '60 days'" condition. If I leave that out, I get results
> from full backups taken a long time ago with job names which are no
> longer in use (i.e. which have been replaced by other jobs also in the
> results of the query). But I can't see a better way to eliminate
> those.
>
> Can anybody suggest an improvement or correction?
>
> Thanks,
> James.
>

-- 
You received this message because you are subscribed to the Google Groups 
"bareos-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/bareos-users/8a2b62a3-ea56-4d3a-8cdd-5fbe24f5e3b1n%40googlegroups.com.

Reply via email to