diff --git a/host-config-bacularis/config-backup.tar b/host-config-bacularis/config-backup.tar new file mode 100644 index 0000000..710257e Binary files /dev/null and b/host-config-bacularis/config-backup.tar differ diff --git a/host-config-bacularis/etc/bacula/bacula-dir.conf b/host-config-bacularis/etc/bacula/bacula-dir.conf new file mode 100644 index 0000000..3c4cd45 --- /dev/null +++ b/host-config-bacularis/etc/bacula/bacula-dir.conf @@ -0,0 +1,285 @@ + +Director { # define myself + Name = buildkitsandbox-dir + DIRport = 9101 # where we listen for UA connections + QueryFile = "/etc/bacula/scripts/query.sql" + WorkingDirectory = "/var/lib/bacula" + PidDirectory = "/run/bacula" + Maximum Concurrent Jobs = 20 + Password = "7srYQCu6W9x-fEVtlnVFKz-tH9L95zh_z" # Console password + Messages = Daemon +} +# Client (File Services) to backup +Client { + Name = buildkitsandbox-fd + Address = localhost + FDPort = 9102 + Catalog = MyCatalog + Password = "oodVpgwlpHIeNmAjtmZK8xV3r6C8OBn3s" # password for FileDaemon + File Retention = 60 days # 60 days + Job Retention = 6 months # six months + AutoPrune = yes # Prune expired Jobs/Files +} +Storage { + Name = "vc0" + SdPort = 9103 + Address = "127.0.0.1" + Password = "hlIl-MqBPNhRMVMwBA2NMbau_wiuNkN-_" + Device = "virtchanger0" + MediaType = "File" + Autochanger = "vc0" + MaximumConcurrentJobs = 20 +} +JobDefs { + Name = "DefaultJob" + Type = Backup + Level = Incremental + Client = buildkitsandbox-fd + FileSet = "Full Set" + Schedule = "WeeklyCycle" + Storage = vc0 + Messages = Standard + Pool = Default + SpoolAttributes = yes + Priority = 10 + Write Bootstrap = "/var/lib/bacula/%c.bsr" +} + + +# +# Define the main nightly save backup job +# By default, this job will back up to disk in /nonexistent/path/to/file/archive/dir +Job { + Name = "BackupClient1" + JobDefs = "DefaultJob" +} + +#Job { +# Name = "BackupClient2" +# Client = buildkitsandbox2-fd +# JobDefs = "DefaultJob" +#} + +#Job { +# Name = "BackupClient1-to-Tape" +# JobDefs = "DefaultJob" +# Storage = LTO-4 +# Spool Data = yes # Avoid shoe-shine +# Pool = Default +#} + +#} + +# Backup the catalog database (after the nightly save) +Job { + Name = "BackupCatalog" + JobDefs = "DefaultJob" + Level = Full + FileSet="Catalog" + Schedule = "WeeklyCycleAfterBackup" + # This creates an ASCII copy of the catalog + # Arguments to make_catalog_backup.pl are: + # make_catalog_backup.pl + RunBeforeJob = "/etc/bacula/scripts/make_catalog_backup.pl MyCatalog" + # This deletes the copy of the catalog + RunAfterJob = "/etc/bacula/scripts/delete_catalog_backup" + Write Bootstrap = "/var/lib/bacula/%n.bsr" + Priority = 11 # run after main backup +} + +# +# Standard Restore template, to be changed by Console program +# Only one such job is needed for all Jobs/Clients/Storage ... +# +Job { + Name = "RestoreFiles" + Type = Restore + Client=buildkitsandbox-fd + Storage = vc0 +# The FileSet and Pool directives are not used by Restore Jobs +# but must not be removed + FileSet="Full Set" + Pool = Default + Messages = Standard + Where = /nonexistent/path/to/file/archive/dir/bacula-restores +} + + +# List of files to be backed up +FileSet { + Name = "Full Set" + Include { + Options { + signature = MD5 + } +# +# Put your list of files here, preceded by 'File =', one per line +# or include an external list with: +# +# File = \" -s \"Bacula: %t %e of %c %l\" %r" + operatorcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: Intervention needed for %j\" %r" + mail = root = all, !skipped + operator = root = mount + console = all, !skipped, !saved +# +# WARNING! the following will create a file that you must cycle from +# time to time as it will grow indefinitely. However, it will +# also keep all your messages if they scroll off the console. +# + append = "/var/log/bacula/bacula.log" = all, !skipped + catalog = all +} + + +# +# Message delivery for daemon messages (no job). +Messages { + Name = Daemon + mailcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula daemon message\" %r" + mail = root = all, !skipped + console = all, !skipped, !saved + append = "/var/log/bacula/bacula.log" = all, !skipped +} + +# Default pool definition +Pool { + Name = Default + Pool Type = Backup + Recycle = yes # Bacula can automatically recycle Volumes + AutoPrune = yes # Prune expired volumes + Volume Retention = 365 days # one year + Maximum Volume Bytes = 50G # Limit Volume size to something reasonable + Maximum Volumes = 100 # Limit number of Volumes in Pool +} +# Scratch pool definition +Pool { + Name = Scratch + Pool Type = Backup +} +# virtual changer pool +Pool { + Name = "VirtualChanger" + PoolType = "Backup" + LabelFormat = "BaculaVol" + PurgeOldestVolume = yes + RecycleOldestVolume = yes + MaximumVolumeBytes = 500000000000 + VolumeRetention = 1209600 + Storage = "vc0" + AutoPrune = yes + Recycle = yes +} +# +# Restricted console used by tray-monitor to get the status of the director +# +Console { + Name = buildkitsandbox-mon + Password = "DZYWFYY6JuWVx3FNRCDNp6LFi7wOH7kxZ" + CommandACL = status, .status +} diff --git a/host-config-bacularis/etc/bacula/bacula-fd.conf b/host-config-bacularis/etc/bacula/bacula-fd.conf new file mode 100644 index 0000000..8f2614c --- /dev/null +++ b/host-config-bacularis/etc/bacula/bacula-fd.conf @@ -0,0 +1,46 @@ +# +# Default Bacula File Daemon Configuration file +# +# There is not much to change here except perhaps the +# File daemon Name to +# +# +# Copyright (C) 2000-2022 Kern Sibbald +# License: BSD 2-Clause; see file LICENSE-FOSS +# + +# +# List Directors who are permitted to contact this File daemon +# +Director { + Name = buildkitsandbox-dir + Password = "oodVpgwlpHIeNmAjtmZK8xV3r6C8OBn3s" +} + +# +# Restricted Director, used by tray-monitor to get the +# status of the file daemon +# +Director { + Name = buildkitsandbox-mon + Password = "xE2sUAmpSBRfSSQKTY99Q6E7TiQWtER0n" + Monitor = yes +} + +# +# "Global" File daemon configuration specifications +# +FileDaemon { # this is me + Name = buildkitsandbox-fd + FDport = 9102 # where we listen for the director + WorkingDirectory = /var/lib/bacula + Pid Directory = /run/bacula + Maximum Concurrent Jobs = 20 + Plugin Directory = /usr/lib/bacula +} + +# Send all messages except skipped files back to Director +Messages { + Name = Standard + director = buildkitsandbox-dir = all, !skipped, !restored, !verified, !saved +} diff --git a/host-config-bacularis/etc/bacula/bacula-sd.conf b/host-config-bacularis/etc/bacula/bacula-sd.conf new file mode 100644 index 0000000..de5edba --- /dev/null +++ b/host-config-bacularis/etc/bacula/bacula-sd.conf @@ -0,0 +1,384 @@ +# +# Default Bacula Storage Daemon Configuration file +# +# You may need to change the name of your tape drive +# on the "Archive Device" directive in the Device +# resource. If you change the Name and/or the +# "Media Type" in the Device resource, please ensure +# that dird.conf has corresponding changes. +# +# +# Copyright (C) 2000-2022 Kern Sibbald +# License: BSD 2-Clause; see file LICENSE-FOSS +# + +Storage { # definition of myself + Name = buildkitsandbox-sd + SDPort = 9103 # Director's port + WorkingDirectory = "/var/lib/bacula" + Pid Directory = "/run/bacula" + Plugin Directory = "/usr/lib/bacula" + Maximum Concurrent Jobs = 20 +} + +# +# List Directors who are permitted to contact Storage daemon +# +Director { + Name = buildkitsandbox-dir + Password = "hlIl-MqBPNhRMVMwBA2NMbau_wiuNkN-_" +} + +# +# Restricted Director, used by tray-monitor to get the +# status of the storage daemon +# +Director { + Name = buildkitsandbox-mon + Password = "mBfawz4FC_LYuXtrYDVJCYQlSSsItLCwO" + Monitor = yes +} + + +Autochanger { + Name = "virtchanger0" + Device = "vc0-drive0" + Device = "vc0-drive1" + Device = "vc0-drive2" + ChangerDevice = "/etc/vchanger/vc0.conf" + ChangerCommand = "vchanger %c %o %S %a %d" +} +Device { + Name = "vc0-drive0" + MediaType = "File" + DeviceType = "File" + ArchiveDevice = "/var/spool/vchanger/vc0/0" + RemovableMedia = yes + RandomAccess = yes + LabelMedia = no + Autochanger = yes + MinimumBlockSize = 1048576 + MaximumBlockSize = 4194304 + MaximumConcurrentJobs = 2 +} +Device { + Name = "vc0-drive1" + MediaType = "File" + DeviceType = "File" + ArchiveDevice = "/var/spool/vchanger/vc0/1" + RemovableMedia = yes + RandomAccess = yes + LabelMedia = no + Autochanger = yes + MinimumBlockSize = 1048576 + MaximumBlockSize = 4194304 + MaximumConcurrentJobs = 2 + DriveIndex = 1 +} +Device { + Name = "vc0-drive2" + MediaType = "File" + DeviceType = "File" + ArchiveDevice = "/var/spool/vchanger/vc0/2" + RemovableMedia = yes + RandomAccess = yes + LabelMedia = no + Autochanger = yes + MinimumBlockSize = 1048576 + MaximumBlockSize = 4194304 + MaximumConcurrentJobs = 2 + DriveIndex = 2 +} + + +# +# Note, for a list of additional Device templates please +# see the directory /examples/devices +# Or follow the following link: +# http://www.bacula.org/git/cgit.cgi/bacula/tree/bacula/examples/devices?h=Branch-7.4 +# + +# +# Devices supported by this Storage daemon +# To connect, the Director's bacula-dir.conf must have the +# same Name and MediaType. +# + +# +# Define a Virtual autochanger +# +Autochanger { + Name = FileChgr1 + Device = FileChgr1-Dev1, FileChgr1-Dev2 + Changer Command = "" + Changer Device = /dev/null +} + +Device { + Name = FileChgr1-Dev1 + Media Type = File1 + Archive Device = /nonexistent/path/to/file/archive/dir + LabelMedia = yes; # lets Bacula label unlabeled media + Random Access = Yes; + AutomaticMount = yes; # when device opened, read it + RemovableMedia = no; + AlwaysOpen = no; + Maximum Concurrent Jobs = 5 +} + +Device { + Name = FileChgr1-Dev2 + Media Type = File1 + Archive Device = /nonexistent/path/to/file/archive/dir + LabelMedia = yes; # lets Bacula label unlabeled media + Random Access = Yes; + AutomaticMount = yes; # when device opened, read it + RemovableMedia = no; + AlwaysOpen = no; + Maximum Concurrent Jobs = 5 +} + +# +# Define a second Virtual autochanger +# +Autochanger { + Name = FileChgr2 + Device = FileChgr2-Dev1, FileChgr2-Dev2 + Changer Command = "" + Changer Device = /dev/null +} + +Device { + Name = FileChgr2-Dev1 + Media Type = File2 + Archive Device = /nonexistent/path/to/file/archive/dir + LabelMedia = yes; # lets Bacula label unlabeled media + Random Access = Yes; + AutomaticMount = yes; # when device opened, read it + RemovableMedia = no; + AlwaysOpen = no; + Maximum Concurrent Jobs = 5 +} + +Device { + Name = FileChgr2-Dev2 + Media Type = File2 + Archive Device = /nonexistent/path/to/file/archive/dir + LabelMedia = yes; # lets Bacula label unlabeled media + Random Access = Yes; + AutomaticMount = yes; # when device opened, read it + RemovableMedia = no; + AlwaysOpen = no; + Maximum Concurrent Jobs = 5 +} + + + +# +# An autochanger device with two drives +# +#Autochanger { +# Name = Autochanger +# Device = Drive-1 +# Device = Drive-2 +# Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d" +# Changer Device = /dev/sg0 +#} + +#Device { +# Name = Drive-1 # +# Drive Index = 0 +# Media Type = DLT-8000 +# Archive Device = /dev/nst0 +# AutomaticMount = yes; # when device opened, read it +# AlwaysOpen = yes; +# RemovableMedia = yes; +# RandomAccess = no; +# AutoChanger = yes +# # +# # New alert command in Bacula 9.0.0 +# # Note: you must have the sg3_utils (rpms) or the +# # sg3-utils (deb) installed on your system. +# # and you must set the correct control device that +# # corresponds to the Archive Device +# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nst0 +# Alert Command = "/etc/bacula/scripts/tapealert %l" +# +# # +# # Enable the Alert command only if you have the mtx package loaded +# # Note, apparently on some systems, tapeinfo resets the SCSI controller +# # thus if you turn this on, make sure it does not reset your SCSI +# # controller. I have never had any problems, and smartctl does +# # not seem to cause such problems. +# # +# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" +# If you have smartctl, enable this, it has more info than tapeinfo +# Alert Command = "sh -c 'smartctl -H -l error %c'" +#} + +#Device { +# Name = Drive-2 # +# Drive Index = 1 +# Media Type = DLT-8000 +# Archive Device = /dev/nst1 +# AutomaticMount = yes; # when device opened, read it +# AlwaysOpen = yes; +# RemovableMedia = yes; +# RandomAccess = no; +# AutoChanger = yes +# # Enable the Alert command only if you have the mtx package loaded +# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" +# If you have smartctl, enable this, it has more info than tapeinfo +# Alert Command = "sh -c 'smartctl -H -l error %c'" +#} + +# +# A Linux or Solaris LTO-2 tape drive +# +#Device { +# Name = LTO-2 +# Media Type = LTO-2 +# Archive Device = /dev/nst0 +# AutomaticMount = yes; # when device opened, read it +# AlwaysOpen = yes; +# RemovableMedia = yes; +# RandomAccess = no; +# Maximum File Size = 3GB +## Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d" +## Changer Device = /dev/sg0 +## AutoChanger = yes +# # Enable the Alert command only if you have the mtx package loaded +## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" +## If you have smartctl, enable this, it has more info than tapeinfo +## Alert Command = "sh -c 'smartctl -H -l error %c'" +#} + +# +# A Linux or Solaris LTO-3 tape drive +# +#Device { +# Name = LTO-3 +# Media Type = LTO-3 +# Archive Device = /dev/nst0 +# AutomaticMount = yes; # when device opened, read it +# AlwaysOpen = yes; +# RemovableMedia = yes; +# RandomAccess = no; +# Maximum File Size = 4GB +# Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d" +# Changer Device = /dev/sg0 +# AutoChanger = yes +# # +# # New alert command in Bacula 9.0.0 +# # Note: you must have the sg3_utils (rpms) or the +# # sg3-utils (deb) installed on your system. +# # and you must set the correct control device that +# # corresponds to the Archive Device +# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nst0 +# Alert Command = "/etc/bacula/scripts/tapealert %l" +# +# # Enable the Alert command only if you have the mtx package loaded +## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" +## If you have smartctl, enable this, it has more info than tapeinfo +## Alert Command = "sh -c 'smartctl -H -l error %c'" +#} + +# +# A Linux or Solaris LTO-4 tape drive +# +#Device { +# Name = LTO-4 +# Media Type = LTO-4 +# Archive Device = /dev/nst0 +# AutomaticMount = yes; # when device opened, read it +# AlwaysOpen = yes; +# RemovableMedia = yes; +# RandomAccess = no; +# Maximum File Size = 5GB +# Changer Command = "/etc/bacula/scripts/mtx-changer %c %o %S %a %d" +# Changer Device = /dev/sg0 +# AutoChanger = yes +# # +# # New alert command in Bacula 9.0.0 +# # Note: you must have the sg3_utils (rpms) or the +# # sg3-utils (deb) installed on your system. +# # and you must set the correct control device that +# # corresponds to the Archive Device +# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nst0 +# Alert Command = "/etc/bacula/scripts/tapealert %l" +# +# # Enable the Alert command only if you have the mtx package loaded +## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" +## If you have smartctl, enable this, it has more info than tapeinfo +## Alert Command = "sh -c 'smartctl -H -l error %c'" +#} + +# +# An HP-UX tape drive +# +#Device { +# Name = Drive-1 # +# Drive Index = 0 +# Media Type = DLT-8000 +# Archive Device = /dev/rmt/1mnb +# AutomaticMount = yes; # when device opened, read it +# AlwaysOpen = yes; +# RemovableMedia = yes; +# RandomAccess = no; +# AutoChanger = no +# Two EOF = yes +# Hardware End of Medium = no +# Fast Forward Space File = no +# # +# # New alert command in Bacula 9.0.0 +# # Note: you must have the sg3_utils (rpms) or the +# # sg3-utils (deb) installed on your system. +# # and you must set the correct control device that +# # corresponds to the Archive Device +# Control Device = /dev/sg?? # must be SCSI ctl for /dev/rmt/1mnb +# Alert Command = "/etc/bacula/scripts/tapealert %l" +# +# # +# # Enable the Alert command only if you have the mtx package loaded +# Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" +# If you have smartctl, enable this, it has more info than tapeinfo +# Alert Command = "sh -c 'smartctl -H -l error %c'" +#} + +# +# A FreeBSD tape drive +# +#Device { +# Name = DDS-4 +# Description = "DDS-4 for FreeBSD" +# Media Type = DDS-4 +# Archive Device = /dev/nsa1 +# AutomaticMount = yes; # when device opened, read it +# AlwaysOpen = yes +# Offline On Unmount = no +# Hardware End of Medium = no +# BSF at EOM = yes +# Backward Space Record = no +# Fast Forward Space File = no +# TWO EOF = yes +# # +# # New alert command in Bacula 9.0.0 +# # Note: you must have the sg3_utils (rpms) or the +# # sg3-utils (deb) installed on your system. +# # and you must set the correct control device that +# # corresponds to the Archive Device +# Control Device = /dev/sg?? # must be SCSI ctl for /dev/nsa1 +# Alert Command = "/etc/bacula/scripts/tapealert %l" +# +# If you have smartctl, enable this, it has more info than tapeinfo +# Alert Command = "sh -c 'smartctl -H -l error %c'" +#} + +# +# Send all messages to the Director, +# mount messages also are sent to the email address +# +Messages { + Name = Standard + director = buildkitsandbox-dir = all +} diff --git a/host-config-bacularis/etc/bacula/bconsole.conf b/host-config-bacularis/etc/bacula/bconsole.conf new file mode 100644 index 0000000..81a3142 --- /dev/null +++ b/host-config-bacularis/etc/bacula/bconsole.conf @@ -0,0 +1,13 @@ +# +# Bacula User Agent (or Console) Configuration File +# +# Copyright (C) 2000-2022 Kern Sibbald +# License: BSD 2-Clause; see file LICENSE-FOSS +# + +Director { + Name = buildkitsandbox-dir + DIRport = 9101 + address = localhost + Password = "7srYQCu6W9x-fEVtlnVFKz-tH9L95zh_z" +} diff --git a/host-config-bacularis/etc/bacula/common_default_passwords b/host-config-bacularis/etc/bacula/common_default_passwords new file mode 100644 index 0000000..766ba47 --- /dev/null +++ b/host-config-bacularis/etc/bacula/common_default_passwords @@ -0,0 +1,12 @@ +# +# This file has been autogenerated during package installation and +# holds defaults for new Bacula packages installed on this system. It +# is used only when you install a new Bacula package, and can be +# safely removed at any time. + +DIRPASSWD=7srYQCu6W9x-fEVtlnVFKz-tH9L95zh_z +DIRMPASSWD=DZYWFYY6JuWVx3FNRCDNp6LFi7wOH7kxZ +SDPASSWD=hlIl-MqBPNhRMVMwBA2NMbau_wiuNkN-_ +SDMPASSWD=mBfawz4FC_LYuXtrYDVJCYQlSSsItLCwO +FDPASSWD=oodVpgwlpHIeNmAjtmZK8xV3r6C8OBn3s +FDMPASSWD=xE2sUAmpSBRfSSQKTY99Q6E7TiQWtER0n diff --git a/host-config-bacularis/etc/bacula/scripts/btraceback.gdb b/host-config-bacularis/etc/bacula/scripts/btraceback.gdb new file mode 100644 index 0000000..d3dff1e --- /dev/null +++ b/host-config-bacularis/etc/bacula/scripts/btraceback.gdb @@ -0,0 +1,17 @@ +print fail_time +print my_name +print exename +print exepath +print assert_msg +print db_engine_name +print version +print host_os +print distname +print distver +print host_name +print dist_name +show env TestName +bt full +thread apply all bt +detach +quit diff --git a/host-config-bacularis/etc/bacula/scripts/disk-changer b/host-config-bacularis/etc/bacula/scripts/disk-changer new file mode 100755 index 0000000..9489cd6 --- /dev/null +++ b/host-config-bacularis/etc/bacula/scripts/disk-changer @@ -0,0 +1,397 @@ +#!/bin/sh +# +# Bacula interface to virtual autoloader using disk storage +# +# Written by Kern Sibbald +# +# Bacula(R) - The Network Backup Solution +# +# Copyright (C) 2000-2022 Kern Sibbald +# +# The original author of Bacula is Kern Sibbald, with contributions +# from many others, a complete list can be found in the file AUTHORS. +# +# You may use this file and others of this release according to the +# license defined in the LICENSE file, which includes the Affero General +# Public License, v3.0 ("AGPLv3") and some additional permissions and +# terms pursuant to its AGPLv3 Section 7. +# +# This notice must be preserved when any source code is +# conveyed and/or propagated. +# +# Bacula(R) is a registered trademark of Kern Sibbald. +# If you set in your Device resource +# +# Changer Command = "path-to-this-script/disk-changer %c %o %S %a %d" +# you will have the following input to this script: +# +# So Bacula will always call with all the following arguments, even though +# in come cases, not all are used. Note, the Volume name is not always +# included. +# +# disk-changer "changer-device" "command" "slot" "archive-device" "drive-index" "volume" +# $1 $2 $3 $4 $5 $6 +# +# By default the autochanger has 10 Volumes and 1 Drive. +# +# Note: For this script to work, you *must" specify +# Device Type = File +# in each of the Devices associated with your AutoChanger resource. +# +# changer-device is the name of a file that overrides the default +# volumes and drives. It may have: +# maxslot=n where n is one based (default 10) +# maxdrive=m where m is zero based (default 1 -- i.e. 2 drives) +# +# This code can also simulate barcodes. You simply put +# a list of the slots and barcodes in the "base" directory/barcodes. +# See below for the base directory definition. Example of a +# barcodes file: +# /var/bacula/barcodes +# 1:Vol001 +# 2:Vol002 +# ... +# +# archive-device is the name of the base directory where you want the +# Volumes stored appended with /drive0 for the first drive; /drive1 +# for the second drive, ... For example, you might use +# /var/bacula/drive0 Note: you must not have a trailing slash, and +# the string (e.g. /drive0) must be unique, and it must not match +# any other part of the directory name. These restrictions could be +# easily removed by any clever script jockey. +# +# Full example: disk-changer /var/bacula/conf load 1 /var/bacula/drive0 0 TestVol001 +# +# The Volumes will be created with names slot1, slot2, slot3, ... maxslot in the +# base directory. In the above example the base directory is /var/bacula. +# However, as with tapes, their Bacula Volume names will be stored inside the +# Volume label. In addition to the Volumes (e.g. /var/bacula/slot1, +# /var/bacula/slot3, ...) this script will create a /var/bacula/loadedn +# file to keep track of what Slot is loaded. You should not change this file. +# +# Modified 8 June 2010 to accept Volume names from the calling program as arg 6. +# In this case, rather than storing the data in slotn, it is stored in the +# Volume name. Note: for this to work, Volume names may not include spaces. +# + +wd=/var/lib/bacula + +# +# log whats done +# +# to turn on logging, uncomment the following line +#touch $wd/disk-changer.log +# +dbgfile="$wd/disk-changer.log" +debug() { + if test -f $dbgfile; then + echo "`date +\"%Y%m%d-%H:%M:%S\"` $*" >> $dbgfile + fi +} + + +# +# Create a temporary file +# +make_temp_file() { + TMPFILE=`mktemp -t mtx.XXXXXXXXXX` + if test x${TMPFILE} = x; then + TMPFILE="$wd/disk-changer.$$" + if test -f ${TMPFILE}; then + echo "Temp file security problem on: ${TMPFILE}" + exit 1 + fi + fi +} + +# check parameter count on commandline +# +check_parm_count() { + pCount=$1 + pCountNeed=$2 + if test $pCount -lt $pCountNeed; then + echo "usage: disk-changer ctl-device command [slot archive-device drive-index]" + echo " Insufficient number of arguments arguments given." + if test $pCount -lt 2; then + echo " Mimimum usage is first two arguments ..." + else + echo " Command expected $pCountNeed arguments" + fi + exit 1 + fi +} + +# +# Strip off the final name in order to get the Directory ($dir) +# that we are dealing with. +# +get_dir() { + bn=`basename $device` + dir=`echo "$device" | sed -e s%/$bn%%g` + if [ ! -d $dir ]; then + echo "ERROR: Autochanger directory \"$dir\" does not exist." + echo " You must create it." + exit 1 + fi +} + +# +# Get the Volume name from the call line, or directly from +# the volslotn information. +# +get_vol() { + havevol=0 + debug "vol=$volume" + if test "x$volume" != x && test "x$volume" != "x*NONE*" ; then + debug "touching $dir/$volume" + touch $dir/$volume + echo "$volume" >$dir/volslot${slot} + havevol=1 + elif [ -f $dir/volslot${slot} ]; then + volume=`cat $dir/volslot${slot}` + havevol=1 + fi +} + + +# Setup arguments +ctl=$1 +cmd="$2" +slot=$3 +device=$4 +drive=$5 +volume=$6 + +# set defaults +maxdrive=1 +maxslot=10 + +# Pull in conf file +if [ -f $ctl ]; then + . $ctl +fi + + +# Check for special cases where only 2 arguments are needed, +# all others are a minimum of 5 +# +case $2 in + list|listall) + check_parm_count $# 2 + ;; + slots) + check_parm_count $# 2 + ;; + transfer) + check_parm_count $# 4 + if [ $slot -gt $maxslot ]; then + echo "Slot ($slot) out of range (1-$maxslot)" + debug "Error: Slot ($slot) out of range (1-$maxslot)" + exit 1 + fi + ;; + *) + check_parm_count $# 5 + if [ $drive -gt $maxdrive ]; then + echo "Drive ($drive) out of range (0-$maxdrive)" + debug "Error: Drive ($drive) out of range (0-$maxdrive)" + exit 1 + fi + if [ $slot -gt $maxslot ]; then + echo "Slot ($slot) out of range (1-$maxslot)" + debug "Error: Slot ($slot) out of range (1-$maxslot)" + exit 1 + fi + ;; +esac + + +debug "Parms: $ctl $cmd $slot $device $drive $volume $havevol" + +case $cmd in + unload) + debug "Doing disk -f $ctl unload $slot $device $drive $volume" + get_dir + if [ -f $dir/loaded${drive} ]; then + ld=`cat $dir/loaded${drive}` + else + echo "Storage Element $slot is Already Full" + debug "Unload error: $dir/loaded${drive} is already unloaded" + exit 1 + fi + if [ $slot -eq $ld ]; then + echo "0" >$dir/loaded${drive} + unlink $device 2>/dev/null >/dev/null + unlink ${device}.add 2>/dev/null >/dev/null + rm -f ${device} ${device}.add + else + echo "Storage Element $slot is Already Full" + debug "Unload error: $dir/loaded${drive} slot=$ld is already unloaded" + exit 1 + fi + ;; + + load) + debug "Doing disk $ctl load $slot $device $drive $volume" + get_dir + i=0 + # Check if slot already in a drive + while [ $i -le $maxdrive ]; do + if [ -f $dir/loaded${i} ]; then + ld=`cat $dir/loaded${i}` + else + ld=0 + fi + if [ $ld -eq $slot ]; then + echo "Drive ${i} Full (Storage element ${ld} loaded)" + debug "Load error: Cannot load Slot=${ld} in drive=$drive. Already in drive=${i}" + exit 1 + fi + i=`expr $i + 1` + done + # Check if we have a Volume name + get_vol + if [ $havevol -eq 0 ]; then + # check if slot exists + if [ ! -f $dir/slot${slot} ] ; then + echo "source Element Address $slot is Empty" + debug "Load error: source Element Address $slot is Empty" + exit 1 + fi + fi + if [ -f $dir/loaded${drive} ]; then + ld=`cat $dir/loaded${drive}` + else + ld=0 + fi + if [ $ld -ne 0 ]; then + echo "Drive ${drive} Full (Storage element ${ld} loaded)" + echo "Load error: Drive ${drive} Full (Storage element ${ld} loaded)" + exit 1 + fi + echo "0" >$dir/loaded${drive} + unlink $device 2>/dev/null >/dev/null + unlink ${device}.add 2>/dev/null >/dev/null + rm -f ${device} ${device}.add + if [ $havevol -ne 0 ]; then + ln -s $dir/$volume $device + ln -s $dir/${volume}.add ${device}.add + rtn=$? + else + ln -s $dir/slot${slot} $device + ln -s $dir/slot${slot}.add ${device}.add + rtn=$? + fi + if [ $rtn -eq 0 ]; then + echo $slot >$dir/loaded${drive} + fi + exit $rtn + ;; + + list) + debug "Doing disk -f $ctl -- to list volumes" + get_dir + if [ -f $dir/barcodes ]; then + cat $dir/barcodes + else + i=1 + while [ $i -le $maxslot ]; do + slot=$i + volume= + get_vol + if [ $havevol -eq 0 ]; then + echo "$i:" + else + echo "$i:$volume" + fi + i=`expr $i + 1` + done + fi + exit 0 + ;; + + listall) + # ***FIXME*** must add new Volume stuff + make_temp_file + debug "Doing disk -f $ctl -- to list volumes" + get_dir + if [ ! -f $dir/barcodes ]; then + exit 0 + fi + + # we print drive content seen by autochanger + # and we also remove loaded media from the barcode list + i=0 + while [ $i -le $maxdrive ]; do + if [ -f $dir/loaded${i} ]; then + ld=`cat $dir/loaded${i}` + v=`awk -F: "/^$ld:/"' { print $2 }' $dir/barcodes` + echo "D:$i:F:$ld:$v" + echo "^$ld:" >> $TMPFILE + fi + i=`expr $i + 1` + done + + # Empty slots are not in barcodes file + # When we detect a gap, we print missing rows as empty + # At the end, we fill the gap between the last entry and maxslot + grep -v -f $TMPFILE $dir/barcodes | sort -n | \ + perl -ne 'BEGIN { $cur=1 } + if (/(\d+):(.+)?/) { + if ($cur == $1) { + print "S:$1:F:$2\n" + } else { + while ($cur < $1) { + print "S:$cur:E\n"; + $cur++; + } + } + $cur++; + } + END { while ($cur < '"$maxslot"') { print "S:$cur:E\n"; $cur++; } } ' + + rm -f $TMPFILE + exit 0 + ;; + transfer) + # ***FIXME*** must add new Volume stuff + get_dir + make_temp_file + slotdest=$device + if [ -f $dir/slot{$slotdest} ]; then + echo "destination Element Address $slot is Full" + exit 1 + fi + if [ ! -f $dir/slot${slot} ] ; then + echo "source Element Address $slot is Empty" + exit 1 + fi + + echo "Transfering $slot to $slotdest" + mv $dir/slot${slot} $dir/slot{$slotdest} + mv $dir/slot${slot}.add $dir/slot{$slotdest}.add + + if [ -f $dir/barcodes ]; then + sed "s/^$slot:/$slotdest:/" > $TMPFILE + sort -n $TMPFILE > $dir/barcodes + fi + exit 0 + ;; + loaded) + debug "Doing disk -f $ctl $drive -- to find what is loaded" + get_dir + if [ -f $dir/loaded${drive} ]; then + a=`cat $dir/loaded${drive}` + else + a="0" + fi + debug "Loaded: drive=$drive is $a" + echo $a + exit + ;; + + slots) + debug "Doing disk -f $ctl -- to get count of slots" + echo $maxslot + ;; +esac diff --git a/host-config-bacularis/etc/bacula/scripts/isworm b/host-config-bacularis/etc/bacula/scripts/isworm new file mode 100755 index 0000000..654833f --- /dev/null +++ b/host-config-bacularis/etc/bacula/scripts/isworm @@ -0,0 +1,84 @@ +#!/bin/sh +# +# Copyright (C) 2000-2020 Kern Sibbald +# License: BSD 2-Clause; see file LICENSE-FOSS +# +# Bacula interface to get worm status of tape +# +# isworm %l (control device name) +# +# Typical output: +# sdparm --page=0x1D -f /dev/sg0 +# /dev/st0: HP Ultrium 5-SCSI I5AW [tape] +# Medium configuration (SSC) mode page: +# WORMM 1 [cha: n, def: 1, sav: 1] +# WMLR 1 [cha: n, def: 1, sav: 1] +# WMFR 2 [cha: n, def: 2, sav: 2] +# +# Where WORMM is worm mode +# WMLR is worm mode label restrictions +# 0 - No blocks can be overwritten +# 1 - Some types of format labels may not be overwritten +# 2 - All format labels can be overwritten +# WMFR is worm mode filemark restrictions +# 0-1 - Reserved +# 2 - Any number of filemarks immediately preceding EOD can be +# overwritten except file mark closest to BOP (beginning of +# partition). +# 3 - Any number of filemarks immediately preceding the EOD +# can be overwritten +# 4-FF - Reserved +# + +if [ x$1 = x ] ; then + echo "First argument missing. Must be device control name." + exit 1 +fi + +sdparm=`which sdparm` +if [ x${sdparm} = x ] ; then + echo "sdparm program not found, but is required." + exit 0 +fi + +# +# This should be the correct way to determine if the tape is WORM +# but it does not work for mhvtl. Comment out the next 5 lines +# and the code that follows will detect correctly on mhtvl. +# +worm=`$sdparm --page=0x1D -f $1 |grep " *WORMM"|cut -b12-16|sed "s:^ *::"` +if [ $? = 0 ] ; then + echo $worm + exit 0 +fi + +tapeinfo=`which tapeinfo` +if [ x${tapeinfo} = x ] ; then + echo "tapeinfo program not found, but is required." + exit 1 +fi + +# +# Unfortunately IBM and HP handle the Medium Type differently, +# so we detect the vendor and get the appropriate Worm flag. +# +vendor=`$tapeinfo -f $1|grep "^Vendor ID:"|cut -b13-15` +if [ x$vendor = xHP ] ; then + worm=`$tapeinfo -f $1|grep "^Medium Type: 0x"|cut -b16-16` + echo $worm + exit 0 +fi + +if [ x$vendor = xIBM ] ; then + worm=`$tapeinfo -f $1|grep "^Medium Type: 0x"|cut -b17-17` + if [ x$worm = xc ]; then + echo "1" + exit 0 + fi + if [ x$worm = xC ]; then + echo "1" + exit 0 + fi +fi +echo "0" +exit 0 diff --git a/host-config-bacularis/etc/bacula/scripts/make_catalog_backup b/host-config-bacularis/etc/bacula/scripts/make_catalog_backup new file mode 100755 index 0000000..c013a50 --- /dev/null +++ b/host-config-bacularis/etc/bacula/scripts/make_catalog_backup @@ -0,0 +1,111 @@ +#!/bin/sh +# +# Copyright (C) 2000-2022 Kern Sibbald +# License: BSD 2-Clause; see file LICENSE-FOSS +# +# This script dumps your Bacula catalog in ASCII format +# It works for MySQL, SQLite, and PostgreSQL +# +# $1 is the name of the database to be backed up and the name +# of the output file (default = bacula). +# $2 is the user name with which to access the database +# (default = bacula). +# $3 is the password with which to access the database or "" if no password +# (default ""). WARNING!!! Passing the password via the command line is +# insecure and should not be used since any user can display the command +# line arguments and the environment using ps. Please consult your +# MySQL or PostgreSQL manual for secure methods of specifying the +# password. +# $4 is the host on which the database is located +# (default "") +# $5 is the type of database +# +# + +default_db_type=postgresql +user=${2:-XXX_DBUSER_XXX} + +# +# See if the fifth argument is a valid backend name. +# If so the user overrides the default database backend. +# +if [ $# -ge 5 ]; then + case $5 in + sqlite3) + db_type=$5 + ;; + mysql) + db_type=$5 + ;; + postgresql) + db_type=$5 + ;; + ingres) + db_type=$5 + ;; + *) + ;; + esac +fi + +# +# If no new db_type is gives use the default db_type. +# +if [ -z "${db_type}" ]; then + db_type="${default_db_type}" +fi + +cd /var/lib/bacula +rm -f $1.sql + +case ${db_type} in + sqlite3) + BINDIR=/usr/bin + echo ".dump" | ${BINDIR}/sqlite3 $1.db >$1.sql + ;; + mysql) + BINDIR=/usr/bin + if test $# -gt 2; then + MYSQLPASSWORD=" --password=$3" + else + MYSQLPASSWORD="" + fi + if test $# -gt 3; then + MYSQLHOST=" --host=$4" + else + MYSQLHOST="" + fi + ${BINDIR}/mysqldump -u ${user}${MYSQLPASSWORD}${MYSQLHOST} -f --opt $1 >$1.sql + ;; + postgresql) + BINDIR=/usr/bin + if test $# -gt 2; then + PGPASSWORD=$3 + export PGPASSWORD + fi + if test $# -gt 3; then + PGHOST=" --host=$4" + else + PGHOST="" + fi + # you could also add --compress for compression. See man pg_dump + exec ${BINDIR}/pg_dump -c $PGHOST -U $user $1 >$1.sql + ;; +esac +# +# To read back a MySQL database use: +# cd /var/lib/bacula +# rm -f ${BINDIR}/../var/bacula/* +# mysql '$wd/$args{db_name}.sql'"); + print "Error while executing sqlite dump $!\n"; + return 1; +} + +# TODO: use just ENV and drop the pg_service.conf file +sub setup_env_pgsql +{ + my %args = @_; + my $username = getpwuid $ENV{'UID'}; + umask(0077); + + if ($args{db_address}) { + $ENV{PGHOST}=$args{db_address}; + } + if ($args{db_socket}) { + $ENV{PGHOST}=$args{db_socket}; + } + if ($args{db_port}) { + $ENV{PGPORT}=$args{db_port}; + } + if ($args{db_user}) { + $ENV{PGUSER}=$args{db_user}; + } + if ($args{db_password}) { + $ENV{PGPASSWORD}=$args{db_password}; + } + $ENV{PGDATABASE}=$args{db_name}; + system("echo '\\q' | HOME='$wd' psql") == 0 or die "$username doesn't have access to the catalog database\n"; +} + +sub dump_pgsql +{ + my %args = @_; + setup_env_pgsql(%args); + exec("HOME='$wd' pg_dump -c > '$wd/$args{db_name}.sql'"); + print "Error while executing postgres dump $!\n"; + return 1; # in case of error +} + +sub analyse_pgsql +{ + my %args = @_; + setup_env_pgsql(%args); + my @output =`LANG=C HOME='$wd' vacuumdb -z 2>&1`; + my $exitcode = $? >> 8; + print grep { !/^WARNING:\s+skipping\s\"(pg_|sql_)/ } @output; + if ($exitcode != 0) { + print "Error while executing postgres analyse. Exitcode=$exitcode\n"; + } + return $exitcode; +} + +sub setup_env_mysql +{ + my %args = @_; + umask(0077); + unlink("$wd/.my.cnf"); + open(MY, ">$wd/.my.cnf") + or die "Can't open $wd/.my.cnf for writing $@"; + + $args{db_address} = $args{db_address} || "localhost"; + my $addr = "host=$args{db_address}"; + if ($args{db_socket}) { # unix socket is fastest than net socket + $addr = "socket=\"$args{db_socket}\""; + } + my $mode = $args{mode} || 'client'; + print MY "[$mode] +$addr +user=\"$args{db_user}\" +password=\"$args{db_password}\" +"; + if ($args{db_port}) { + print MY "port=$args{db_port}\n"; + } + close(MY); +} + +sub dump_mysql +{ + my %args = @_; + + setup_env_mysql(%args); + exec("HOME='$wd' mysqldump -f --opt $args{db_name} > '$wd/$args{db_name}.sql'"); + print "Error while executing mysql dump $!\n"; + return 1; +} + +sub analyse_mysql +{ + my %args = @_; + + $args{mode} = 'mysqlcheck'; + setup_env_mysql(%args); + + exec("HOME='$wd' mysqlcheck -a $args{db_name}"); + print "Error while executing mysql analyse $!\n"; + return 1; +} + +sub handle_catalog +{ + my ($mode, %args) = @_; + if (exists $args{working_dir} and $wd ne $args{working_dir}) { + $wd = $args{working_dir}; + } + if ($args{db_type} eq 'SQLite3') { + $ENV{PATH}="/usr/bin:$ENV{PATH}"; + if ($mode eq 'dump') { + dump_sqlite3(%args); + } + } elsif ($args{db_type} eq 'PostgreSQL') { + $ENV{PATH}="/usr/bin:$ENV{PATH}"; + if ($mode eq 'dump') { + dump_pgsql(%args); + } else { + analyse_pgsql(%args); + } + } elsif ($args{db_type} eq 'MySQL') { + $ENV{PATH}="/usr/bin:$ENV{PATH}"; + if ($mode eq 'dump') { + dump_mysql(%args); + } else { + analyse_mysql(%args); + } + } else { + die "This database type isn't supported"; + } +} + +open(FP, "$dir_conf -C '$cat'|") or die "Can't get catalog information $@"; +# catalog=MyCatalog +# db_type=SQLite +# db_name=regress +# db_driver= +# db_user=regress +# db_password= +# db_address= +# db_port=0 +# db_socket= +my %cfg; + +while(my $l = ) +{ + if ($l =~ /catalog=(.+)/) { + if (exists $cfg{catalog} and $cfg{catalog} eq $cat) { + exit handle_catalog($mode, %cfg); + } + %cfg = (); # reset + } + + if ($l =~ /(\w+)=(.+)/) { + $cfg{$1}=$2; + } +} + +if (exists $cfg{catalog} and $cfg{catalog} eq $cat) { + exit handle_catalog($mode, %cfg); +} + +print "Can't find your catalog ($cat) in director configuration\n"; +exit 1; diff --git a/host-config-bacularis/etc/bacula/scripts/mtx-changer b/host-config-bacularis/etc/bacula/scripts/mtx-changer new file mode 100755 index 0000000..a0dc873 --- /dev/null +++ b/host-config-bacularis/etc/bacula/scripts/mtx-changer @@ -0,0 +1,353 @@ +#!/bin/sh +# +# Bacula(R) - The Network Backup Solution +# +# Copyright (C) 2000-2022 Kern Sibbald +# +# The original author of Bacula is Kern Sibbald, with contributions +# from many others, a complete list can be found in the file AUTHORS. +# +# You may use this file and others of this release according to the +# license defined in the LICENSE file, which includes the Affero General +# Public License, v3.0 ("AGPLv3") and some additional permissions and +# terms pursuant to its AGPLv3 Section 7. +# +# This notice must be preserved when any source code is +# conveyed and/or propagated. +# +# Bacula(R) is a registered trademark of Kern Sibbald. +# +# If you set in your Device resource +# +# Changer Command = "path-to-this-script/mtx-changer %c %o %S %a %d" +# you will have the following input to this script: +# +# So Bacula will always call with all the following arguments, even though +# in come cases, not all are used. +# +# mtx-changer "changer-device" "command" "slot" "archive-device" "drive-index" +# $1 $2 $3 $4 $5 +# +# for example: +# +# mtx-changer /dev/sg0 load 1 /dev/nst0 0 (on a Linux system) +# +# will request to load the first cartidge into drive 0, where +# the SCSI control channel is /dev/sg0, and the read/write device +# is /dev/nst0. +# +# The commands are: +# Command Function +# unload unload a given slot +# load load a given slot +# loaded which slot is loaded? +# list list Volume names (requires barcode reader) +# slots how many slots total? +# listall list all info +# transfer +# +# Slots are numbered from 1 ... +# Drives are numbered from 0 ... +# +# +# If you need to an offline, refer to the drive as $4 +# e.g. mt -f $4 offline +# +# Many changers need an offline after the unload. Also many +# changers need a sleep 60 after the mtx load. +# +# N.B. If you change the script, take care to return either +# the mtx exit code or a 0. If the script exits with a non-zero +# exit code, Bacula will assume the request failed. +# + +# myversion must be the same as version in mtx-changer.conf +myversion=2 + +# source our conf file +if test ! -f /etc/bacula/scripts/mtx-changer.conf ; then + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "ERROR: /etc/bacula/scripts/mtx-changer.conf file not found!!!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + exit 1 +fi +. /etc/bacula/scripts/mtx-changer.conf + +if test "${version}" != "${myversion}" ; then + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "ERROR: /etc/bacula/scripts/mtx-changer.conf has wrong version. Wanted ${myversion}, got ${version} !!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + exit 1 +fi + +MTX=/usr/sbin/mtx + +if test ${debug_log} -ne 0 ; then + touch /var/lib/bacula/mtx.log +fi +dbgfile="/var/lib/bacula/mtx.log" +debug() { + if test -f $dbgfile -a ${debug_level} -ge $1; then + echo "`date +%m%d-%H:%M:%S.%N|cut -c1-16` ${chgr_id} $2" >> $dbgfile + fi +} + + +# +# Create a temporary file +# +make_temp_file() { + TMPFILE=`mktemp /var/lib/bacula/mtx.XXXXXXXXXX` + if test x${TMPFILE} = x; then + TMPFILE="/var/lib/bacula/mtx.$$" + if test -f ${TMPFILE}; then + echo "ERROR: Temp file security problem on: ${TMPFILE}" + exit 1 + fi + fi +} + +# +# Create a temporary file for stderr +# +# Note, this file is used because sometime mtx emits +# unexpected error messages followed by the output +# expected during success. +# So we separate STDOUT and STDERR in +# certain of the mtx commands. The contents of STDERR +# is then printed after the STDOUT produced by mtx +# thus we sometimes get better changer results. +# +make_err_file() { + ERRFILE=`mktemp /var/lib/bacula/mtx.err.XXXXXXXXXX` + if test x${ERRFILE} = x; then + ERRFILE="/var/lib/bacula/mtx.err.$$" + if test -f ${ERRFILE}; then + echo "ERROR: Temp file security problem on: ${ERRFILE}" + exit 1 + fi + fi +} + + +# +# The purpose of this function to wait a maximum +# time for the drive. It will +# return as soon as the drive is ready, or after +# waiting a maximum of 300 seconds. +# Note, this is very system dependent, so if you are +# not running on Linux, you will probably need to +# re-write it, or at least change the grep target. +# We've attempted to get the appropriate OS grep targets +# in the code at the top of this script. +# +wait_for_drive() { + i=0 + while [ $i -le 300 ]; do # Wait max 300 seconds + if mt -f $1 status 2>&1 | grep "${ready}" >/dev/null 2>&1; then + break + fi + debug $dbglvl "Device $1 - not ready, retrying..." + sleep 1 + i=`expr $i + 1` + done +} + +# check parameter count on commandline +# +check_parm_count() { + pCount=$1 + pCountNeed=$2 + if test $pCount -lt $pCountNeed; then + echo "ERROR: usage: mtx-changer ctl-device command [slot archive-device drive-index]" + echo " Insufficient number of arguments given." + if test $pCount -lt 2; then + echo " Mimimum usage is first two arguments ..." + else + echo " Command expected $pCountNeed arguments" + fi + exit 1 + fi +} + +# Check for special cases where only 2 arguments are needed, +# all others are a minimum of 5 +# +case $2 in + list|listall) + check_parm_count $# 2 + ;; + slots) + check_parm_count $# 2 + ;; + transfer) + check_parm_count $# 4 + ;; + *) + check_parm_count $# 5 + ;; +esac + + +# Setup arguments +ctl=$1 +cmd="$2" +slot=$3 +device=$4 +drive=$5 + +debug $dbglvl "Parms: $ctl $cmd $slot $device $drive" + +case $cmd in + unload) + + if test ${offline} -eq 1 ; then + mt -f $device offline + fi + if test ${offline_sleep} -ne 0 ; then + sleep ${offline_sleep} + fi + make_err_file + for i in 1 2 3 4 5 ; do + debug $idbglvl "Doing mtx -f $ctl unload slot=$slot drv=$drive" + ${MTX} -f $ctl unload $slot $drive 2>${ERRFILE} + rtn=$? + if test $rtn -eq 0 ; then + break + fi + grep "Error Code=" ${ERRFILE} 2>/dev/null 1>/dev/null + if test $? -ne 0 ; then + break + fi + sleep $i + done + cat ${ERRFILE} + rm -f ${ERRFILE} >/dev/null 2>&1 + if test $rtn -ne 0 ; then + debug $idbglvl "FAIL: mtx -f $ctl unload slot=$slot drv=$drive" + fi + exit $rtn + ;; + + load) + make_err_file + for i in 1 2 3 4 5 ; do + debug $idbglvl "Doing mtx -f $ctl load slot=$slot drv=$drive" + ${MTX} -f $ctl load $slot $drive 2>${ERRFILE} + rtn=$? + if test $rtn -eq 0 ; then + break + fi + grep "Error Code=" ${ERRFILE} 2>/dev/null 1>/dev/null + if test $? -ne 0 ; then + break + fi + sleep $i + done + if test ${load_sleep} -ne 0 ; then + sleep ${load_sleep} + fi + wait_for_drive $device + cat ${ERRFILE} + rm -f ${ERRFILE} >/dev/null 2>&1 + if test $rtn -ne 0 ; then + debug $idbglvl "FAIL: mtx -f $ctl load slot=$slot drv=$drive" + fi + exit $rtn + ;; + + list) + make_temp_file + if test ${inventory} -ne 0 ; then + ${MTX} -f $ctl inventory + fi + debug $dbglvl "Doing mtx -f $ctl list" + ${MTX} -f $ctl status >${TMPFILE} + rtn=$? + if test ${vxa_packetloader} -ne 0 ; then + cat ${TMPFILE} | grep " *Storage Element [0-9]*:.*Full" | sed "s/ *Storage Element //" | sed "s/Full :VolumeTag=//" + else + cat ${TMPFILE} | grep " Storage Element [0-9]*:.*Full" | awk "{print \$3 \$4}" | sed "s/Full *\(:VolumeTag=\)*//" + fi + cat ${TMPFILE} | grep "^Data Transfer Element [0-9]*:Full (Storage Element [0-9]" | awk '{printf "%s:%s\n",$7,$10}' + rm -f ${TMPFILE} >/dev/null 2>&1 + if test $rtn -ne 0 ; then + debug $idbglvl "FAIL: mtx -f $ctl list" + fi + exit $rtn + ;; + + listall) +# Drive content: D:Drive num:F:Slot loaded:Volume Name +# D:0:F:2:vol2 or D:Drive num:E +# D:1:F:42:vol42 +# D:3:E +# +# Slot content: +# S:1:F:vol1 S:Slot num:F:Volume Name +# S:2:E or S:Slot num:E +# S:3:F:vol4 +# +# Import/Export tray slots: +# I:10:F:vol10 I:Slot num:F:Volume Name +# I:11:E or I:Slot num:E +# I:12:F:vol40 + + make_temp_file + if test ${inventory} -ne 0 ; then + ${MTX} -f $ctl inventory + fi + debug $dbglvl "Doing mtx -f $ctl -- to list all" + ${MTX} -f $ctl status >${TMPFILE} + rtn=$? + # can be converted to awk+sed+cut, see below + perl -ne ' +/Data Transfer Element (\d+):Empty/ && print "D:$1:E\n"; +/Data Transfer Element (\d+):Full \(Storage Element (\d+) Loaded\)(:VolumeTag =\s*(.+))?/ && print "D:$1:F:$2:$4\n"; +/Storage Element (\d+):Empty/ && print "S:$1:E\n"; +/Storage Element (\d+):Full( :VolumeTag=(.+))?/ && print "S:$1:F:$3\n"; +/Storage Element (\d+) IMPORT.EXPORT:Empty/ && print "I:$1:E\n"; +/Storage Element (\d+) IMPORT.EXPORT:Full( :VolumeTag=(.+))?/ && print "I:$1:F:$3\n";' ${TMPFILE} + # If perl isn't installed, you can use by those commands +#cat ${TMPFILE} | grep "Data Transfer Element" | awk "{print \"D:\"\$4 \$7 \$9 \$10}" | sed "s/=/:/" | sed "s/Full/F:/" | sed "s/Empty/E/" +#cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep -v "IMPORT/EXPORT" | awk "{print \"S:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/" +#cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep "IMPORT/EXPORT" | awk "{print \"I:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/" + + rm -f ${TMPFILE} >/dev/null 2>&1 + exit $rtn + ;; + + transfer) + slotdest=$device + debug $dbglvl "Doing transfer from $slot to $slotdest" + ${MTX} -f $ctl transfer $slot $slotdest + rtn=$? + if test $rtn -ne 0 ; then + debug $idbglvl "FAIL: mtx -f $ctl transfer from=$slot to=$slotdest" + fi + exit $rtn + ;; + + loaded) + make_temp_file + debug $idbglvl "Doing mtx -f $ctl $drive -- to find what is loaded" + ${MTX} -f $ctl status >${TMPFILE} + rtn=$? + cat ${TMPFILE} | grep "^Data Transfer Element $drive:Full" | awk "{print \$7}" + cat ${TMPFILE} | grep "^Data Transfer Element $drive:Empty" | awk "{print 0}" + rm -f ${TMPFILE} >/dev/null 2>&1 + if test $rtn -ne 0 ; then + debug $idbglvl "FAIL: mtx -f $ctl loaded drv=$drive" + fi + exit $rtn + ;; + + slots) + debug $dbglvl "Doing mtx -f $ctl -- to get count of slots" + ${MTX} -f $ctl status | grep " *Storage Changer" | awk "{print \$5}" + rtn=$? + if test $rtn -ne 0 ; then + debug $idbglvl "FAIL: mtx -f $ctl slots" + fi + ;; +esac diff --git a/host-config-bacularis/etc/bacula/scripts/mtx-changer.conf b/host-config-bacularis/etc/bacula/scripts/mtx-changer.conf new file mode 100644 index 0000000..8d51170 --- /dev/null +++ b/host-config-bacularis/etc/bacula/scripts/mtx-changer.conf @@ -0,0 +1,95 @@ +# +# Copyright (C) 2000-2015 Kern Sibbald +# License: BSD 2-Clause; see file LICENSE-FOSS +# +# +# This file is sourced by the mtx-changer script every time it runs. +# You can put your site customization here, and when you do an +# upgrade, the process should not modify this file. Thus you +# preserve your mtx-changer configuration. +# + +# We update the version when an incompatible change +# to mtx-changer or this conf file is made, such as +# adding a new required variable. +version=2 + +# Set to 1 if you want to do offline before unload +offline=0 + +# Set to amount of time in seconds to wait after an offline +offline_sleep=0 + +# Set to amount of time in seconds to wait after a load +load_sleep=0 + +# Set to 1 to do an inventory before a status. Not normally needed. +inventory=0 + +# If you have a VXA PacketLoader, it might display a different +# Storage Element line, so try setting the following to 1 +vxa_packetloader=0 + +# +# Debug logging +# + +# If you have multiple SD's, set this differently for each one +# so you know which message comes from which one. This can +# be any string, and will appear in each debug message just +# after the time stamp. +chgr_id=0 + +# Set to 1 if you want debug info written to a log +debug_log=0 + +# Set to debug level you want to see +# 0 is off +# 10 is important events (load, unload, loaded) +# 100 is everything +# Note debug_log must be set to 1 for anything to be generated +# +debug_level=10 + +# Debug levels by importance +# Normally you do not need to change this +dbglvl=100 +# More important messages +idbglvl=10 + +# +# mt status output +# SunOS No Additional Sense +# FreeBSD Current Driver State: at rest. +# Linux ONLINE +# Note Debian has a different mt than the standard Linux version. +# When no tape is in the drive it waits 2 minutes. +# When a tape is in the drive, it prints user unfriendly output. +# Note, with Ubuntu Gusty (8.04), there are two versions of mt, +# so we attempt to figure out which one. +# Note, with mt GNU cpio, we use "drive status" output +# + +OS=`uname` +case ${OS} in + SunOS) + ready="No Additional Sense" + ;; + FreeBSD) + ready="Current Driver State: at rest." + ;; + Linux) + ready="ONLINE" + if test -f /etc/debian_version ; then + mt --version|grep "mt-st" >/dev/null 2>&1 + if test $? -eq 1 ; then + ready="drive status" + fi + else + mt --version|grep "GNU cpio" >/dev/null 2>&1 + if test $? -eq 0 ; then + ready="drive status" + fi + fi + ;; +esac diff --git a/host-config-bacularis/etc/bacula/scripts/query.sql b/host-config-bacularis/etc/bacula/scripts/query.sql new file mode 100644 index 0000000..585d159 --- /dev/null +++ b/host-config-bacularis/etc/bacula/scripts/query.sql @@ -0,0 +1,7 @@ +# +# See the file /examples/sample-query.sql or /opt/bacula/scripts/sample-query.sql +# for some sample queries. +# +# 1 +:The default file is empty, see /opt/bacula/scripts/sample-query.sql for samples +SELECT 'See /opt/bacula/scripts/sample-query.sql for samples' AS Info; diff --git a/host-config-bacularis/etc/bacula/scripts/tapealert b/host-config-bacularis/etc/bacula/scripts/tapealert new file mode 100755 index 0000000..42a3dd4 --- /dev/null +++ b/host-config-bacularis/etc/bacula/scripts/tapealert @@ -0,0 +1,72 @@ +#!/bin/sh +# +# Copyright (C) 2000-2016 Kern Sibbald +# License: BSD 2-Clause; see file LICENSE-FOSS +# +# Bacula interface to tapeinfo to get tape alerts +# +# tapealert %l (control device name) +# +# Note: you must have in your SD Device resource: +# Alert Command = /full-path/tapealert %l +# Control Device = /dev/sg0n (where this is the scsi control +# device for the device you are using). +# + +# Note: to test +# 1. uncomment out the DEBUG=1 line below +# 2. Possibly remove or add TapeAlert[nn]: that you want to test. +# Note, the message following the : is not used. +# 3. Run Bacula +# +#DEBUG=1 + +tapeinfo=`which tapeinfo` + +if [ x${tapeinfo} = x ] ; then + echo "tapeinfo program not found, but is required." + exit 1 +fi +if [ x$1 = x ] ; then + echo "First argument missing. Must be device control name." + exit 1 +fi + + +if [ x$DEBUG = x ] ; then +out=`mktemp` +$tapeinfo -f $1 >$out +ret=$? +awk '/^TapeAlert/ { $1=""; gsub(/^ */, "", $0); print $0 }' $out +rm -f $out +exit $ret + +else + +# For testing only +cat <