0051_MobaXterm macros: 09.Debian-Backup and Recovery

9.1 Backup Tools and Services
9.2 Scheduled Backup Jobs
9.3 Backup Repositories and Destinations
9.4 Backup Storage Capacity
9.5 Recent Backup Activity
9.6 Backup Failures
9.7 Backup Inventory and Latest Backup
9.8 Backup Integrity and Verification
9.9 Snapshot Technologies
9.10 Proxmox VE Backup Configuration
9.11 Proxmox Backup Server
9.12 Recovery Readiness
9.13 Backup Summary

Why Base64?
Base64 encoding allows complex multi-line Bash scripts to be safely delivered as a single command, avoiding issues with line breaks, quoting, and macro parsing while preserving the original script intact. Use: printf %s <base64_data_ | base64 -d | bash

printf %s 'IyEvdXNyL2Jpbi9lbnYgYmFzaAoKIyA9PT09PT09PT09PT09PT09PT09PSAwOS4gQkFDS1VQICYgUkVDT1ZFUlkgPT09PT09PT09PT09PT09PT09PT0KCmVjaG8gIj09PT09PT09PT09PT09PT09PT09IDA5LiBCQUNLVVAgJiBSRUNPVkVSWSA9PT09PT09PT09PT09PT09PT09PSIKcHJpbnRmICJcbiIKCiMgLS0tIDkuMSBCQUNLVVAgVE9PTFMgQU5EIFNFUlZJQ0VTIC0tLQplY2hvICI5LjEgQkFDS1VQIFRPT0xTIEFORCBTRVJWSUNFUyIKU0NIRURVTEVSX1NUQVRFPSJJTkFDVElWRSIKaWYgc3lzdGVtY3RsIGlzLWFjdGl2ZSBjcm9uID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgU0NIRURVTEVSX1NUQVRFPSJBQ1RJVkUgKGNyb24pIgplbGlmIHN5c3RlbWN0bCBpcy1hY3RpdmUgY3JvbmQgPi9kZXYvbnVsbCAyPiYxOyB0aGVuCiAgICBTQ0hFRFVMRVJfU1RBVEU9IkFDVElWRSAoY3JvbmQpIgplbGlmIHN5c3RlbWN0bCBpcy1hY3RpdmUgc3lzdGVtZC10aW1lcnMudGFyZ2V0ID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgU0NIRURVTEVSX1NUQVRFPSJBQ1RJVkUgKHN5c3RlbWQtdGltZXJzKSIKZmkKZWNobyAiU2NoZWR1bGVyIFN0YXR1cyA6ICRTQ0hFRFVMRVJfU1RBVEUiCmVjaG8KZWNobyAiLS0tIEJhY2t1cCBCaW5hcmllcyAvIEVuZ2luZXMgRGV0ZWN0aW9uIC0tLSIKCkJBQ0tVUF9UT09MU19GT1VORD0wCgppZiBjb21tYW5kIC12IHJzeW5jID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgcHJpbnRmICIgICUtMjJzIDogRk9VTkQgKCVzKQoiICJyc3luYyIgIiQoY29tbWFuZCAtdiByc3luYykiCiAgICBCQUNLVVBfVE9PTFNfRk9VTkQ9JCgoQkFDS1VQX1RPT0xTX0ZPVU5EICsgMSkpCmVsc2UKICAgIHByaW50ZiAiICAlLTIycyA6IE5PVCBGT1VORAoiICJyc3luYyIKZmkKCmlmIGNvbW1hbmQgLXYgYm9yZyA+L2Rldi9udWxsIDI+JjE7IHRoZW4KICAgIHByaW50ZiAiICAlLTIycyA6IEZPVU5EICglcykKIiAiYm9yZyIgIiQoY29tbWFuZCAtdiBib3JnKSIKICAgIEJBQ0tVUF9UT09MU19GT1VORD0kKChCQUNLVVBfVE9PTFNfRk9VTkQgKyAxKSkKZWxzZQogICAgcHJpbnRmICIgICUtMjJzIDogTk9UIEZPVU5ECiIgImJvcmciCmZpCgppZiBjb21tYW5kIC12IHJlc3RpYyA+L2Rldi9udWxsIDI+JjE7IHRoZW4KICAgIHByaW50ZiAiICAlLTIycyA6IEZPVU5EICglcykKIiAicmVzdGljIiAiJChjb21tYW5kIC12IHJlc3RpYykiCiAgICBCQUNLVVBfVE9PTFNfRk9VTkQ9JCgoQkFDS1VQX1RPT0xTX0ZPVU5EICsgMSkpCmVsc2UKICAgIHByaW50ZiAiICAlLTIycyA6IE5PVCBGT1VORAoiICJyZXN0aWMiCmZpCgppZiBjb21tYW5kIC12IGR1cGxpY2l0eSA+L2Rldi9udWxsIDI+JjE7IHRoZW4KICAgIHByaW50ZiAiICAlLTIycyA6IEZPVU5EICglcykKIiAiZHVwbGljaXR5IiAiJChjb21tYW5kIC12IGR1cGxpY2l0eSkiCiAgICBCQUNLVVBfVE9PTFNfRk9VTkQ9JCgoQkFDS1VQX1RPT0xTX0ZPVU5EICsgMSkpCmVsc2UKICAgIHByaW50ZiAiICAlLTIycyA6IE5PVCBGT1VORAoiICJkdXBsaWNpdHkiCmZpCgppZiBjb21tYW5kIC12IHByb3htb3gtYmFja3VwLWNsaWVudCA+L2Rldi9udWxsIDI+JjE7IHRoZW4KICAgIHByaW50ZiAiICAlLTIycyA6IEZPVU5EICglcykKIiBcCiAgICAgICAgInByb3htb3gtYmFja3VwLWNsaWVudCIgXAogICAgICAgICIkKGNvbW1hbmQgLXYgcHJveG1veC1iYWNrdXAtY2xpZW50KSIKICAgIEJBQ0tVUF9UT09MU19GT1VORD0kKChCQUNLVVBfVE9PTFNfRk9VTkQgKyAxKSkKZWxzZQogICAgcHJpbnRmICIgICUtMjJzIDogTk9UIEZPVU5ECiIgInByb3htb3gtYmFja3VwLWNsaWVudCIKZmkKcHJpbnRmICJcbiUuMHMiIHsxLi4zfQoKIyAtLS0gOS4yIFNDSEVEVUxFRCBCQUNLVVAgSk9CUyAtLS0KZWNobyAiOS4yIFNDSEVEVUxFRCBCQUNLVVAgSk9CUyIKQkFDS1VQX0pPQlNfRk9VTkQ9MAplY2hvICItLS0gc3lzdGVtZCBCYWNrdXAgVGltZXJzIC0tLSIKVElNRVJTX0xJU1Q9JChzeXN0ZW1jdGwgbGlzdC10aW1lcnMgLS1hbGwgLS1uby1wYWdlciAyPi9kZXYvbnVsbCB8IGdyZXAgLUVpICdiYWNrdXB8Ym9yZ3xyZXN0aWN8cHZlfHZ6ZHVtcHxzbmFwJykKaWYgWyAtbiAiJFRJTUVSU19MSVNUIiBdOyB0aGVuCiAgICBlY2hvICIkVElNRVJTX0xJU1QiCiAgICBCQUNLVVBfSk9CU19GT1VORD0kKChCQUNLVVBfSk9CU19GT1VORCArIDEpKQplbHNlCiAgICBlY2hvICJObyBleHBsaWNpdCBiYWNrdXAgc3lzdGVtZCB0aW1lcnMgZm91bmQiCmZpCmVjaG8KZWNobyAiLS0tIFN5c3RlbSBDcm9udGFicyAmIEN1c3RvbSBEZWZpbml0aW9ucyAtLS0iCkNST05fVFJBRkZJQz0kKGdyZXAgLUVpICdiYWNrdXB8Ym9yZ3xyZXN0aWN8cnN5bmN8dnpkdW1wJyAvZXRjL2Nyb250YWIgL2V0Yy9jcm9uLmQvKiAvdmFyL3Nwb29sL2Nyb24vY3JvbnRhYnMvKiAyPi9kZXYvbnVsbCkKaWYgWyAtbiAiJENST05fVFJBRkZJQyIgXTsgdGhlbgogICAgZWNobyAiJENST05fVFJBRkZJQyIgfCBoZWFkIC00MAogICAgQkFDS1VQX0pPQlNfRk9VTkQ9JCgoQkFDS1VQX0pPQlNfRk9VTkQgKyAxKSkKZWxzZQogICAgZWNobyAiTm8gYmFja3VwIGpvYnMgZm91bmQgaW4gc3lzdGVtIGNyb250YWJzIgpmaQplY2hvCmVjaG8gIi0tLSBHbG9iYWwgQ3JvbiBEaXJlY3RvcmllcyAtLS0iCkNST05fRElSX1NDUklQVFM9JChmaW5kIC9ldGMvY3Jvbi5ob3VybHkgL2V0Yy9jcm9uLmRhaWx5IC9ldGMvY3Jvbi53ZWVrbHkgL2V0Yy9jcm9uLm1vbnRobHkgLW1heGRlcHRoIDEgLXR5cGUgZiAyPi9kZXYvbnVsbCB8IGdyZXAgLUVpICdiYWNrdXB8Ym9yZ3xyZXN0aWN8cnN5bmN8c25hcCcpCmlmIFsgLW4gIiRDUk9OX0RJUl9TQ1JJUFRTIiBdOyB0aGVuCiAgICBlY2hvICIkQ1JPTl9ESVJfU0NSSVBUUyIKICAgIEJBQ0tVUF9KT0JTX0ZPVU5EPSQoKEJBQ0tVUF9KT0JTX0ZPVU5EICsgMSkpCmVsc2UKICAgIGVjaG8gIk5vIGV4cGxpY2l0IGJhY2t1cCBzY3JpcHRzIGZvdW5kIGluIGNyb24gZGlyZWN0b3JpZXMiCmZpCnByaW50ZiAiXG4lLjBzIiB7MS4uM30KCiMgLS0tIDkuMyBCQUNLVVAgUkVQT1NJVE9SSUVTIEFORCBERVNUSU5BVElPTlMgLS0tCgplY2hvICI5LjMgQkFDS1VQIFJFUE9TSVRPUklFUyBBTkQgREVTVElOQVRJT05TIgoKZWNobyAiLS0tIEFjdGl2ZSBCYWNrdXAgTW91bnRwb2ludHMgLS0tIgoKVEFSR0VUX01PVU5UU19GT1VORD0wCgp3aGlsZSBJRlM9IHJlYWQgLXIgVEFSR0VUOyBkbwogICAgWyAteiAiJFRBUkdFVCIgXSAmJiBjb250aW51ZQoKICAgIFRBUkdFVF9NT1VOVFNfRk9VTkQ9JCgoVEFSR0VUX01PVU5UU19GT1VORCArIDEpKQoKICAgIE9QVElPTlM9JCgKICAgICAgICB0aW1lb3V0IDMgZmluZG1udCBcCiAgICAgICAgICAgIC1ybiBcCiAgICAgICAgICAgIC1UICIkVEFSR0VUIiBcCiAgICAgICAgICAgIC1vIE9QVElPTlMgXAogICAgICAgICAgICAyPi9kZXYvbnVsbAogICAgKQoKICAgIGlmIGVjaG8gIiRPUFRJT05TIiB8IGdyZXAgLUVxICcoXnwsKXJvKCx8JCknOyB0aGVuCiAgICAgICAgZWNobyAiSU5GTzogJFRBUkdFVCBpcyBtb3VudGVkIHJlYWQtb25seSIKICAgICAgICBjb250aW51ZQogICAgZmkKCiAgICBURVNUX0ZJTEU9IiRUQVJHRVQvLmJhY2t1cF93cml0ZV90ZXN0XyQkIgoKICAgIGlmIHRpbWVvdXQgMyB0b3VjaCAiJFRFU1RfRklMRSIgMj4vZGV2L251bGwgJiYgWyAtZiAiJFRFU1RfRklMRSIgXTsgdGhlbgogICAgICAgIGVjaG8gIk9LOiAkVEFSR0VUIGlzIHdyaXRhYmxlIgogICAgICAgIHJtIC1mIC0tICIkVEVTVF9GSUxFIgogICAgZWxzZQogICAgICAgIGVjaG8gIldBUk5JTkc6ICRUQVJHRVQgaXMgbm90IHdyaXRhYmxlIG9yIG5vdCByZXNwb25kaW5nIgogICAgZmkKZG9uZSA8IDwoCiAgICB0aW1lb3V0IDUgZmluZG1udCBcCiAgICAgICAgLXJuIFwKICAgICAgICAtdCBuZnMsbmZzNCxjaWZzLHZmYXQsZXh0NCx4ZnMsemZzIFwKICAgICAgICAtbyBUQVJHRVQgXAogICAgICAgIDI+L2Rldi9udWxsIHwgXAogICAgICAgIGdyZXAgLUVpICdiYWNrdXB8cHZlfHBic3xib3JnfHJlc3RpY3x1c2J8YmFja3VwX3N0b3JhZ2UnCikKCmlmIFsgIiRUQVJHRVRfTU9VTlRTX0ZPVU5EIiAtZXEgMCBdOyB0aGVuCiAgICBlY2hvICJObyBkZWRpY2F0ZWQgYmFja3VwIG1vdW50cG9pbnRzIGRpc2NvdmVyZWQiCmZpCgpwcmludGYgIlxuJS4wcyIgezEuLjN9CgojIC0tLSA5LjQgQkFDS1VQIFNUT1JBR0UgQ0FQQUNJVFkgLS0tCmVjaG8gIjkuNCBCQUNLVVAgU1RPUkFHRSBDQVBBQ0lUWSIKZWNobyAiLS0tIEZpbGVzeXN0ZW0gQ2FwYWNpdHkgLS0tIgpERl9PVVRQVVQ9JCh0aW1lb3V0IDggZGYgLWhUIDI+L2Rldi9udWxsKQppZiBbIC1uICIkREZfT1VUUFVUIiBdOyB0aGVuCiAgICBlY2hvICIkREZfT1VUUFVUIiB8IGdyZXAgLUVpICdGaWxlc3lzdGVtfFR5cGV8YmFja3VwfHB2ZXxwYnN8Ym9yZ3xyZXN0aWN8bmZzfGNpZnN8dXNiJyB8fCBlY2hvICIkREZfT1VUUFVUIiB8IGhlYWQgLTI1CmVsc2UKICAgIGVjaG8gIkZpbGVzeXN0ZW0gY2FwYWNpdHkgcXVlcnkgdW5hdmFpbGFibGUgb3IgdGltZWQgb3V0IgpmaQplY2hvCmVjaG8gIi0tLSBJbm9kZSBDYXBhY2l0eSAtLS0iCkRGX0lOT0RFX09VVFBVVD0kKHRpbWVvdXQgOCBkZiAtaWggMj4vZGV2L251bGwpCmlmIFsgLW4gIiRERl9JTk9ERV9PVVRQVVQiIF07IHRoZW4KICAgIGVjaG8gIiRERl9JTk9ERV9PVVRQVVQiIHwgZ3JlcCAtRWkgJ0ZpbGVzeXN0ZW18VHlwZXxiYWNrdXB8cHZlfHBic3xib3JnfHJlc3RpY3xuZnN8Y2lmc3x1c2InIHx8IGVjaG8gIiRERl9JTk9ERV9PVVRQVVQiIHwgaGVhZCAtMjUKZWxzZQogICAgZWNobyAiSW5vZGUgY2FwYWNpdHkgcXVlcnkgdW5hdmFpbGFibGUgb3IgdGltZWQgb3V0IgpmaQpwcmludGYgIlxuJS4wcyIgezEuLjN9CgojIC0tLSA5LjUgUkVDRU5UIEJBQ0tVUCBBQ1RJVklUWSAtLS0KZWNobyAiOS41IFJFQ0VOVCBCQUNLVVAgQUNUSVZJVFkiCkJBQ0tVUF9TVUNDRVNTX0ZPVU5EPTAKaWYgY29tbWFuZCAtdiBqb3VybmFsY3RsID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgZWNobyAiLS0tIEJhY2t1cC1yZWxhdGVkIFVuaXQgQWN0aXZpdHk6IExhc3QgNyBEYXlzIC0tLSIKICAgIGpvdXJuYWxjdGwgLXUgJ2JvcmcqJyAtdSAncmVzdGljKicgLXUgJ3Z6ZHVtcConIC11ICdwcm94bW94LWJhY2t1cConIC0tc2luY2UgIjcgZGF5cyBhZ28iIC0tbm8tcGFnZXIgMj4vZGV2L251bGwgfCB0YWlsIC01MCB8fCBlY2hvICJObyBiYWNrdXAgdW5pdCBhY3Rpdml0eSBmb3VuZCIKICAgIGVjaG8KZWNobyAiLS0tIFN1Y2Nlc3NmdWwgQmFja3VwIE1hcmtlcnM6IExhc3QgNyBEYXlzIC0tLSIKICAgIExPR1NfU1VDQ0VTUz0kKGpvdXJuYWxjdGwgLS1zaW5jZSAiNyBkYXlzIGFnbyIgLS1uby1wYWdlciAyPi9kZXYvbnVsbCB8IGdyZXAgLUVpICdiYWNrdXB8Ym9yZ3xyZXN0aWN8cnN5bmN8dnpkdW1wfHByb3htb3gtYmFja3VwJyB8IGdyZXAgLUVpICdzdWNjZXNzfGZpbmlzaGVkfGNvbXBsZXRlfGNvbXBsZXRlZHxkb25lfFRBU0sgT0snIHwgdGFpbCAtMTUpCiAgICBpZiBbIC1uICIkTE9HU19TVUNDRVNTIiBdOyB0aGVuCiAgICAgICAgZWNobyAiJExPR1NfU1VDQ0VTUyIKICAgICAgICBCQUNLVVBfU1VDQ0VTU19GT1VORD0xCiAgICBlbHNlCiAgICAgICAgZWNobyAiTm8gZXhwbGljaXQgc3VjY2Vzc2Z1bCBiYWNrdXAgbWFya2VycyBmb3VuZCIKICAgIGZpCmVsc2UKICAgIExPR1NfU1VDQ0VTUz0kKGdyZXAgLUVpaCAnYmFja3VwfGJvcmd8cmVzdGljfHJzeW5jfHZ6ZHVtcCcgL3Zhci9sb2cvc3lzbG9nIC92YXIvbG9nL21lc3NhZ2VzIDI+L2Rldi9udWxsIHwgZ3JlcCAtRWkgJ3N1Y2Nlc3N8ZmluaXNofGNvbXBsZXRlfGRvbmUnIHwgdGFpbCAtMTUpCiAgICBpZiBbIC1uICIkTE9HU19TVUNDRVNTIiBdOyB0aGVuCiAgICAgICAgZWNobyAiJExPR1NfU1VDQ0VTUyIKICAgICAgICBCQUNLVVBfU1VDQ0VTU19GT1VORD0xCiAgICBlbHNlCiAgICAgICAgZWNobyAiTm8gc3VjY2Vzc2Z1bCBiYWNrdXAgbWFya2VycyBmb3VuZCBpbiBsZWdhY3kgbG9ncyIKICAgIGZpCmZpCnByaW50ZiAiXG4lLjBzIiB7MS4uM30KCiMgLS0tIDkuNiBCQUNLVVAgRkFJTFVSRVMgLS0tCmVjaG8gIjkuNiBCQUNLVVAgRkFJTFVSRVMiCmlmIGNvbW1hbmQgLXYgam91cm5hbGN0bCA+L2Rldi9udWxsIDI+JjE7IHRoZW4KICAgIEJBQ0tVUF9GQUlMVVJFUz0kKGpvdXJuYWxjdGwgLS1zaW5jZSAiNyBkYXlzIGFnbyIgLS1uby1wYWdlciAyPi9kZXYvbnVsbCB8IGdyZXAgLUVpICdiYWNrdXB8Ym9yZ3xyZXN0aWN8cnN5bmN8dnpkdW1wfHByb3htb3gtYmFja3VwJyB8IGdyZXAgLUVpICdmYWlsfGVycm9yfGFib3J0fGNyaXRpY2FsfGZhaWxlZCB3aXRofFRBU0sgRVJST1InIHwgdGFpbCAtMjApCmVsc2UKICAgIEJBQ0tVUF9GQUlMVVJFUz0kKGdyZXAgLUVpaCAnYmFja3VwfGJvcmd8cmVzdGljfHJzeW5jfHZ6ZHVtcCcgL3Zhci9sb2cvc3lzbG9nIC92YXIvbG9nL21lc3NhZ2VzIDI+L2Rldi9udWxsIHwgZ3JlcCAtRWkgJ2ZhaWx8ZXJyb3J8YWJvcnR8Y3JpdGljYWwnIHwgdGFpbCAtMjApCmZpCmlmIFsgLW4gIiRCQUNLVVBfRkFJTFVSRVMiIF07IHRoZW4KICAgIGVjaG8gIiRCQUNLVVBfRkFJTFVSRVMiCmVsc2UKICAgIGVjaG8gIk5vIGJhY2t1cCBmYWlsdXJlIG1hcmtlcnMgZm91bmQgZHVyaW5nIHRoZSBsYXN0IDcgZGF5cyIKZmkKcHJpbnRmICJcbiUuMHMiIHsxLi4zfQoKIyAtLS0gOS43IEJBQ0tVUCBJTlZFTlRPUlkgQU5EIExBVEVTVCBCQUNLVVAgLS0tCmVjaG8gIjkuNyBCQUNLVVAgSU5WRU5UT1JZIEFORCBMQVRFU1QgQkFDS1VQIgpMQVRFU1RfQkFDS1VQX01BUks9JChmaW5kIC92YXIvbG9nIC9iYWNrdXAqIC9tbnQgL29wdCAteGRldiAtdHlwZSBmIFwoIC1pbmFtZSAnKmJhY2t1cConIC1vIC1pbmFtZSAnKi5iYWsnIC1vIC1pbmFtZSAnKi50Z3onIC1vIC1pbmFtZSAnKi50YXIuZ3onIC1vIC1pbmFtZSAnKi52bWEqJyAtbyAtaW5hbWUgJyoucHhhcicgLW8gLWluYW1lICcqLnZ6ZHVtcCcgXCkgLXByaW50ZiAnJVRAfCVwXG4nIDI+L2Rldi9udWxsIHwgc29ydCAtdCAnfCcgLWsxLDFuciB8IGhlYWQgLTEpCmlmIFsgLW4gIiRMQVRFU1RfQkFDS1VQX01BUksiIF07IHRoZW4KICAgIEVQT0NIX1RJTUU9JHtMQVRFU1RfQkFDS1VQX01BUkslJXwqfQogICAgRklMRV9OQU1FPSR7TEFURVNUX0JBQ0tVUF9NQVJLIyp8fQoKICAgIEVQT0NIX1NFQ09ORFM9JHtFUE9DSF9USU1FJSUuKn0KCiAgICBjYXNlICIkRVBPQ0hfU0VDT05EUyIgaW4KICAgICAgICAnJ3wqWyEwLTldKikKICAgICAgICAgICAgRVBPQ0hfU0VDT05EUz0wCiAgICAgICAgICAgIDs7CiAgICBlc2FjCgogICAgQ1VSUkVOVF9FUE9DSD0kKGRhdGUgKyVzKQoKICAgIGlmIFsgIiRFUE9DSF9TRUNPTkRTIiAtZ3QgMCBdICYmIFsgIiRDVVJSRU5UX0VQT0NIIiAtZ2UgIiRFUE9DSF9TRUNPTkRTIiBdOyB0aGVuCiAgICAgICAgQUdFX0RBWVM9JCgoIChDVVJSRU5UX0VQT0NIIC0gRVBPQ0hfU0VDT05EUykgLyA4NjQwMCApKQogICAgZWxzZQogICAgICAgIEFHRV9EQVlTPTk5OQogICAgZmkKCiAgICBlY2hvICJMYXRlc3QgbWF0Y2hpbmcgYmFja3VwIG9iamVjdCA6ICRGSUxFX05BTUUiCiAgICBlY2hvICJUaW1lc3RhbXAgICAgICAgICAgICAgICAgICAgICA6ICQoZGF0ZSAtZCAiQCRFUE9DSF9TRUNPTkRTIiArIiVZLSVtLSVkICVIOiVNOiVTIiAyPi9kZXYvbnVsbCB8fCBkYXRlIC1yICIkRklMRV9OQU1FIiArIiVZLSVtLSVkICVIOiVNOiVTIiAyPi9kZXYvbnVsbCkiCiAgICBlY2hvICJDYWxjdWxhdGVkIGFnZSAgICAgICAgICAgICAgICA6ICRBR0VfREFZUyBkYXkocykiCmVsc2UKICAgIGVjaG8gIk5vIG1hdGNoaW5nIGxvY2FsIGJhY2t1cCBvYmplY3RzIGZvdW5kIGJ5IGZpbGVuYW1lIHBhdHRlcm4iCmZpCnByaW50ZiAiXG4lLjBzIiB7MS4uM30KCiMgLS0tIDkuOCBCQUNLVVAgSU5URUdSSVRZIEFORCBWRVJJRklDQVRJT04gLS0tCmVjaG8gIjkuOCBCQUNLVVAgSU5URUdSSVRZIEFORCBWRVJJRklDQVRJT04iCmVjaG8gIi0tLSBCb3JnIFJlcG9zaXRvcnkgSW52ZW50b3J5IC0tLSIKaWYgY29tbWFuZCAtdiBib3JnID4vZGV2L251bGwgMj4mMTsgdGhlbiB0aW1lb3V0IDEwIGJvcmcgbGlzdCAyPi9kZXYvbnVsbCB8IGhlYWQgLTE1IHx8IGVjaG8gIkJvcmcgcmVwb3NpdG9yeSB1bmF2YWlsYWJsZSwgdW5jb25maWd1cmVkLCBvciBjcmVkZW50aWFscyBtaXNzaW5nIjsgZWxzZSBlY2hvICJCb3JnIG5vdCBpbnN0YWxsZWQiOyBmaQplY2hvCmVjaG8gIi0tLSBSZXN0aWMgU25hcHNob3QgSW52ZW50b3J5IC0tLSIKaWYgY29tbWFuZCAtdiByZXN0aWMgPi9kZXYvbnVsbCAyPiYxOyB0aGVuIHRpbWVvdXQgMTAgcmVzdGljIHNuYXBzaG90cyAyPi9kZXYvbnVsbCB8IGhlYWQgLTE1IHx8IGVjaG8gIlJlc3RpYyByZXBvc2l0b3J5IHVuYXZhaWxhYmxlLCB1bmNvbmZpZ3VyZWQsIG9yIGNyZWRlbnRpYWxzIG1pc3NpbmciOyBlbHNlIGVjaG8gIlJlc3RpYyBub3QgaW5zdGFsbGVkIjsgZmkKZWNobwplY2hvICItLS0gUEJTIFZlcmlmeSBKb2JzIC0tLSIKaWYgY29tbWFuZCAtdiBwcm94bW94LWJhY2t1cC1tYW5hZ2VyID4vZGV2L251bGwgMj4mMTsgdGhlbiBwcm94bW94LWJhY2t1cC1tYW5hZ2VyIHZlcmlmeS1qb2IgbGlzdCAyPi9kZXYvbnVsbCB8fCBlY2hvICJQQlMgdmVyaWZ5IGpvYnMgdW5hdmFpbGFibGUiOyBlbHNlIGVjaG8gIlByb3htb3ggQmFja3VwIFNlcnZlciB0b29scyBub3QgaW5zdGFsbGVkIjsgZmkKZWNobwplY2hvICItLS0gTG9jYWwgU3RvcmFnZSBDb25zaXN0ZW5jeSBDb250ZXh0IC0tLSIKaWYgY29tbWFuZCAtdiB6cG9vbCA+L2Rldi9udWxsIDI+JjE7IHRoZW4genBvb2wgc3RhdHVzIDI+L2Rldi9udWxsIHwgZ3JlcCAtRSAncG9vbDp8c3RhdGU6fHNjYW46fGVycm9yczonIHx8IGVjaG8gIk5vIFpGUyBwb29sIHN0YXR1cyBhdmFpbGFibGUiOyBmaQppZiBbIC1mIC9wcm9jL21kc3RhdCBdOyB0aGVuIGdyZXAgLUUgJ2FjdGl2ZXxpbmFjdGl2ZXxyZWNvdmVyeXxyZXN5bmN8cmVzaGFwZXxjaGVja3xcW1tVX10rXF0nIC9wcm9jL21kc3RhdCAyPi9kZXYvbnVsbCB8fCBjYXQgL3Byb2MvbWRzdGF0IDI+L2Rldi9udWxsOyBmaQpwcmludGYgIlxuJS4wcyIgezEuLjN9CgojIC0tLSA5LjkgU05BUFNIT1QgVEVDSE5PTE9HSUVTIC0tLQplY2hvICI5LjkgU05BUFNIT1QgVEVDSE5PTE9HSUVTIgplY2hvICItLS0gTFZNIFNuYXBzaG90cyAtLS0iCmlmIGNvbW1hbmQgLXYgbHZzID4vZGV2L251bGwgMj4mMTsgdGhlbiBsdnMgLWEgMj4vZGV2L251bGwgfCBncmVwIC1FaSAnc25hcCcgfHwgZWNobyAiTm8gTFZNIHNuYXBzaG90cyBkZXRlY3RlZCI7IGVsc2UgZWNobyAiTFZNIHRvb2xzIG5vdCBpbnN0YWxsZWQiOyBmaQplY2hvCmVjaG8gIi0tLSBaRlMgU25hcHNob3RzIC0tLSIKaWYgY29tbWFuZCAtdiB6ZnMgPi9kZXYvbnVsbCAyPiYxOyB0aGVuIHpmcyBsaXN0IC10IHNuYXBzaG90IDI+L2Rldi9udWxsIHwgaGVhZCAtMjUgfHwgZWNobyAiTm8gWkZTIHNuYXBzaG90cyBkZXRlY3RlZCI7IGVsc2UgZWNobyAiWkZTIHRvb2xzIG5vdCBpbnN0YWxsZWQiOyBmaQplY2hvCmVjaG8gIi0tLSBCdHJmcyBTbmFwc2hvdHMgLS0tIgppZiBjb21tYW5kIC12IGJ0cmZzID4vZGV2L251bGwgMj4mMTsgdGhlbiBidHJmcyBzdWJ2b2x1bWUgbGlzdCAtcyAvIDI+L2Rldi9udWxsIHx8IGVjaG8gIk5vIEJ0cmZzIHNuYXBzaG90cyBkZXRlY3RlZCBvciByb290IGlzIG5vdCBCdHJmcyI7IGVsc2UgZWNobyAiQnRyZnMgdG9vbHMgbm90IGluc3RhbGxlZCI7IGZpCnByaW50ZiAiXG4lLjBzIiB7MS4uM30KCiMgLS0tIDkuMTAgUFJPWE1PWCBWRSBCQUNLVVAgQ09ORklHVVJBVElPTiAtLS0KZWNobyAiOS4xMCBQUk9YTU9YIFZFIEJBQ0tVUCBDT05GSUdVUkFUSU9OIgppZiBbIC1kIC9ldGMvcHZlIF07IHRoZW4KICAgIGVjaG8gIi0tLSBQQlMgU3RvcmFnZSBEZWZpbml0aW9ucyAtLS0iCiAgICBncmVwIC1BIDEyIC1FICdecGJzOicgL2V0Yy9wdmUvc3RvcmFnZS5jZmcgMj4vZGV2L251bGwgfHwgZWNobyAiTm8gUEJTIHN0b3JhZ2UgZGVmaW5pdGlvbnMgZm91bmQiCiAgICBlY2hvCmVjaG8gIi0tLSBQcm94bW94IFN0b3JhZ2UgU3RhdHVzIC0tLSIKICAgIHB2ZXNtIHN0YXR1cyAyPi9kZXYvbnVsbCB8fCBlY2hvICJQVkUgc3RvcmFnZSBzdGF0dXMgdW5hdmFpbGFibGUiCiAgICBlY2hvCmVjaG8gIi0tLSBTY2hlZHVsZWQgQmFja3VwIEpvYnMgLS0tIgogICAgaWYgWyAtZiAvZXRjL3B2ZS9qb2JzLmNmZyBdOyB0aGVuIGNhdCAvZXRjL3B2ZS9qb2JzLmNmZzsgZWxpZiBbIC1mIC9ldGMvcHZlL3Z6ZHVtcC5jcm9uIF07IHRoZW4gY2F0IC9ldGMvcHZlL3Z6ZHVtcC5jcm9uOyBlbHNlIGVjaG8gIk5vIHNjaGVkdWxlZCB2emR1bXAgam9icyBmb3VuZCI7IGZpCiAgICBlY2hvCmVjaG8gIi0tLSBDbHVzdGVyIEJhY2t1cCBBUEkgLS0tIgogICAgdGltZW91dCA1IHB2ZXNoIGdldCAvY2x1c3Rlci9iYWNrdXAgLS1vdXRwdXQtZm9ybWF0IHlhbWwgMj4vZGV2L251bGwgfCBoZWFkIC00MCB8fCBlY2hvICJQVkUgYmFja3VwIEFQSSBtZXRhZGF0YSB1bmF2YWlsYWJsZSIKZWxzZQogICAgZWNobyAiUHJveG1veCBWRSBlbnZpcm9ubWVudCBub3QgZGV0ZWN0ZWQiCmZpCnByaW50ZiAiXG4lLjBzIiB7MS4uM30KCiMgLS0tIDkuMTEgUFJPWE1PWCBCQUNLVVAgU0VSVkVSIC0tLQoKZWNobyAiOS4xMSBQUk9YTU9YIEJBQ0tVUCBTRVJWRVIiCgppZiBjb21tYW5kIC12IHByb3htb3gtYmFja3VwLW1hbmFnZXIgPi9kZXYvbnVsbCAyPiYxOyB0aGVuCiAgICBlY2hvICItLS0gUEJTIERhdGFzdG9yZXMgLS0tIgoKICAgIHByb3htb3gtYmFja3VwLW1hbmFnZXIgZGF0YXN0b3JlIGxpc3QgMj4vZGV2L251bGwgfHwgXAogICAgICAgIGVjaG8gIlBCUyBkYXRhc3RvcmUgaW5mb3JtYXRpb24gdW5hdmFpbGFibGUiCgogICAgZWNobwoKICAgIGVjaG8gIi0tLSBQQlMgUHJ1bmUgSm9icyAtLS0iCgogICAgcHJveG1veC1iYWNrdXAtbWFuYWdlciBwcnVuZS1qb2IgbGlzdCAyPi9kZXYvbnVsbCB8fCBcCiAgICAgICAgZWNobyAiUEJTIHBydW5lIGpvYnMgdW5hdmFpbGFibGUiCgogICAgZWNobwoKICAgIGVjaG8gIi0tLSBQQlMgVmVyaWZ5IEpvYnMgLS0tIgoKICAgIHByb3htb3gtYmFja3VwLW1hbmFnZXIgdmVyaWZ5LWpvYiBsaXN0IDI+L2Rldi9udWxsIHx8IFwKICAgICAgICBlY2hvICJQQlMgdmVyaWZ5IGpvYnMgdW5hdmFpbGFibGUiCgogICAgZWNobwoKICAgIGVjaG8gIi0tLSBQQlMgR2FyYmFnZSBDb2xsZWN0aW9uIFN0YXR1cyBieSBEYXRhc3RvcmUgLS0tIgoKICAgIERBVEFTVE9SRV9OQU1FUz0kKAogICAgICAgIHByb3htb3gtYmFja3VwLW1hbmFnZXIgZGF0YXN0b3JlIGxpc3QgXAogICAgICAgICAgICAtLW91dHB1dC1mb3JtYXQganNvbiBcCiAgICAgICAgICAgIDI+L2Rldi9udWxsIHwgXAogICAgICAgIHB5dGhvbjMgLWMgJwppbXBvcnQganNvbgppbXBvcnQgc3lzCgp0cnk6CiAgICBkYXRhID0ganNvbi5sb2FkKHN5cy5zdGRpbikKZXhjZXB0IEV4Y2VwdGlvbjoKICAgIHN5cy5leGl0KDEpCgpmb3IgaXRlbSBpbiBkYXRhOgogICAgbmFtZSA9IGl0ZW0uZ2V0KCJuYW1lIikgb3IgaXRlbS5nZXQoInN0b3JlIikKICAgIGlmIG5hbWU6CiAgICAgICAgcHJpbnQobmFtZSkKJyAyPi9kZXYvbnVsbAogICAgKQoKICAgIGlmIFsgLXogIiREQVRBU1RPUkVfTkFNRVMiIF07IHRoZW4KICAgICAgICBEQVRBU1RPUkVfTkFNRVM9JCgKICAgICAgICAgICAgcHJveG1veC1iYWNrdXAtbWFuYWdlciBkYXRhc3RvcmUgbGlzdCBcCiAgICAgICAgICAgICAgICAyPi9kZXYvbnVsbCB8IFwKICAgICAgICAgICAgYXdrICcKICAgICAgICAgICAgICAgIE5SID09IDEge25leHR9CiAgICAgICAgICAgICAgICAvXltbOnNwYWNlOl1dKiQvIHtuZXh0fQogICAgICAgICAgICAgICAgJDEgfiAvXlstK3xdKyQvIHtuZXh0fQogICAgICAgICAgICAgICAge3ByaW50ICQxfQogICAgICAgICAgICAnCiAgICAgICAgKQogICAgZmkKCiAgICBpZiBbIC1uICIkREFUQVNUT1JFX05BTUVTIiBdOyB0aGVuCiAgICAgICAgd2hpbGUgSUZTPSByZWFkIC1yIERBVEFTVE9SRTsgZG8KICAgICAgICAgICAgWyAteiAiJERBVEFTVE9SRSIgXSAmJiBjb250aW51ZQoKICAgICAgICAgICAgZWNobyAiRGF0YXN0b3JlOiAkREFUQVNUT1JFIgoKICAgICAgICAgICAgcHJveG1veC1iYWNrdXAtbWFuYWdlciBcCiAgICAgICAgICAgICAgICBnYXJiYWdlLWNvbGxlY3Rpb24gc3RhdHVzICIkREFUQVNUT1JFIiBcCiAgICAgICAgICAgICAgICAyPi9kZXYvbnVsbCB8fCBcCiAgICAgICAgICAgICAgICBlY2hvICJHYXJiYWdlIGNvbGxlY3Rpb24gc3RhdHVzIHVuYXZhaWxhYmxlIGZvciAkREFUQVNUT1JFIgoKICAgICAgICAgICAgZWNobwogICAgICAgIGRvbmUgPDw8ICIkREFUQVNUT1JFX05BTUVTIgogICAgZWxzZQogICAgICAgIGVjaG8gIk5vIFBCUyBkYXRhc3RvcmVzIGZvdW5kIGZvciBnYXJiYWdlIGNvbGxlY3Rpb24gc3RhdHVzIgogICAgZmkKCiAgICBlY2hvICItLS0gUEJTIFJlY2VudCBUYXNrcyAtLS0iCgogICAgcHJveG1veC1iYWNrdXAtbWFuYWdlciB0YXNrIGxpc3QgMj4vZGV2L251bGwgfCBcCiAgICAgICAgaGVhZCAtMjAgfHwgXAogICAgICAgIGVjaG8gIlBCUyB0YXNrIGhpc3RvcnkgdW5hdmFpbGFibGUiCmVsc2UKICAgIGVjaG8gIlByb3htb3ggQmFja3VwIFNlcnZlciB0b29scyBub3QgZGV0ZWN0ZWQiCmZpCgpwcmludGYgIlxuJS4wcyIgezEuLjN9CgojIC0tLSA5LjEyIFJFQ09WRVJZIFJFQURJTkVTUyAtLS0KZWNobyAiOS4xMiBSRUNPVkVSWSBSRUFESU5FU1MiClJFQ09WRVJZX1ZBTElEPTEKaWYgWyAiJEJBQ0tVUF9UT09MU19GT1VORCIgLWVxIDAgXSAmJiBbICEgLWQgL2V0Yy9wdmUgXSAmJiAhIGNvbW1hbmQgLXYgcHJveG1veC1iYWNrdXAtbWFuYWdlciA+L2Rldi9udWxsIDI+JjE7IHRoZW4KICAgIGVjaG8gIkNSSVRJQ0FMOiBObyBiYWNrdXAgdG9vbHMgb3IgUHJveG1veCBiYWNrdXAgc3RhY2sgZGV0ZWN0ZWQiCiAgICBSRUNPVkVSWV9WQUxJRD0wCmVsc2UKICAgIGVjaG8gIk9LOiBCYWNrdXAgdG9vbGluZyBvciBwbGF0Zm9ybSBiYWNrdXAgc3RhY2sgZGV0ZWN0ZWQiCmZpCmlmIFsgLW4gIiRMQVRFU1RfQkFDS1VQX01BUksiIF07IHRoZW4KICAgIGlmIFsgIiR7QUdFX0RBWVM6LTk5OX0iIC1sZSA3IF07IHRoZW4gZWNobyAiT0s6IExhdGVzdCBtYXRjaGluZyBiYWNrdXAgb2JqZWN0IGlzICRBR0VfREFZUyBkYXkocykgb2xkIjsgZWxzZSBlY2hvICJXQVJOSU5HOiBMYXRlc3QgbWF0Y2hpbmcgYmFja3VwIG9iamVjdCBpcyAkQUdFX0RBWVMgZGF5KHMpIG9sZCI7IFJFQ09WRVJZX1ZBTElEPTA7IGZpCmVsc2UKICAgIGVjaG8gIldBUk5JTkc6IE5vIGxvY2FsIGJhY2t1cCBvYmplY3QgZGV0ZWN0ZWQgYnkgZmlsZW5hbWUgcGF0dGVybiIKICAgIFJFQ09WRVJZX1ZBTElEPTAKZmkKaWYgWyAiJEJBQ0tVUF9TVUNDRVNTX0ZPVU5EIiAtZXEgMSBdOyB0aGVuIGVjaG8gIk9LOiBBdCBsZWFzdCBvbmUgc3VjY2Vzc2Z1bCBiYWNrdXAgbWFya2VyIGZvdW5kIGluIHRoZSBsYXN0IDcgZGF5cyI7IGVsc2UgZWNobyAiV0FSTklORzogTm8gZXhwbGljaXQgc3VjY2Vzc2Z1bCBiYWNrdXAgbWFya2VyIGZvdW5kIGluIHRoZSBsYXN0IDcgZGF5cyI7IGZpCmVjaG8KZWNobyAiLS0tIFJvb3QgRmlsZXN5c3RlbSBIZWFkcm9vbSAtLS0iCmRmIC1oIC8gMj4vZGV2L251bGwgfHwgZWNobyAiUm9vdCBmaWxlc3lzdGVtIGNhcGFjaXR5IHVuYXZhaWxhYmxlIgpwcmludGYgIlxuJS4wcyIgezEuLjN9CgojIC0tLSA5LjEzIEJBQ0tVUCBTVU1NQVJZIC0tLQplY2hvICI5LjEzIEJBQ0tVUCBTVU1NQVJZIgplY2hvICItLS0gQmFja3VwIGFuZCBSZWNvdmVyeSBTdW1tYXJ5IC0tLSIKZWNobyAiU2NoZWR1bGVyLi4uLi4uLi4uLi4uLi4uLiRTQ0hFRFVMRVJfU1RBVEUiCmlmIFsgIiRCQUNLVVBfVE9PTFNfRk9VTkQiIC1ndCAwIF07IHRoZW4gZWNobyAiQmFja3VwIFRvb2wuLi4uLi4uLi4uLi4uLkZPVU5EICgkQkFDS1VQX1RPT0xTX0ZPVU5EIGluc3RhbGxlZCB0b29sKHMpKSI7IGVsc2UgZWNobyAiQmFja3VwIFRvb2wuLi4uLi4uLi4uLi4uLk5PVCBGT1VORCI7IGZpCmlmIFsgIiRCQUNLVVBfSk9CU19GT1VORCIgLWd0IDAgXTsgdGhlbiBlY2hvICJCYWNrdXAgSm9iLi4uLi4uLi4uLi4uLi4uRk9VTkQiOyBlbHNlIGVjaG8gIkJhY2t1cCBKb2IuLi4uLi4uLi4uLi4uLi5OT1QgRk9VTkQiOyBmaQppZiBbICIkVEFSR0VUX01PVU5UU19GT1VORCIgLWd0IDAgXTsgdGhlbiBlY2hvICJSZXBvc2l0b3J5Li4uLi4uLi4uLi4uLi4uRk9VTkQgLyBNT1VOVEVEIjsgZWxzZSBlY2hvICJSZXBvc2l0b3J5Li4uLi4uLi4uLi4uLi4uTk9UIEZPVU5EIEJZIE1PVU5UUE9JTlQgUEFUVEVSTiI7IGZpCmlmIFsgLW4gIiRMQVRFU1RfQkFDS1VQX01BUksiIF07IHRoZW4gTEFTVF9CQUNLVVBfREFURT0kKGRhdGUgLWQgIkAkRVBPQ0hfU0VDT05EUyIgKyIlWS0lbS0lZCIgMj4vZGV2L251bGwgfHwgZGF0ZSAtciAiJEZJTEVfTkFNRSIgKyIlWS0lbS0lZCIgMj4vZGV2L251bGwpOyBlY2hvICJMYXN0IEJhY2t1cCBNYXRjaC4uLi4uLi4uJHtMQVNUX0JBQ0tVUF9EQVRFOi1VTktOT1dOfSAoJEFHRV9EQVlTIGRheShzKSBhZ28pIjsgZWxzZSBlY2hvICJMYXN0IEJhY2t1cCBNYXRjaC4uLi4uLi4uTk9UIERFVEVDVEVEIjsgZmkKaWYgWyAiJEJBQ0tVUF9TVUNDRVNTX0ZPVU5EIiAtZXEgMSBdOyB0aGVuIGVjaG8gIlJlY2VudCBTdWNjZXNzIE1hcmtlci4uLi5GT1VORCI7IGVsc2UgZWNobyAiUmVjZW50IFN1Y2Nlc3MgTWFya2VyLi4uLk5PVCBGT1VORCI7IGZpCmlmIFsgIiRSRUNPVkVSWV9WQUxJRCIgLWVxIDEgXTsgdGhlbiBlY2hvICJSZWNvdmVyeSBSZWFkaW5lc3MuLi4uLi4uT0siOyBlbHNlIGVjaG8gIlJlY292ZXJ5IFJlYWRpbmVzcy4uLi4uLi5XQVJOSU5HIjsgZmkK' | base64 -d | bash
# ==================== 09. BACKUP & RECOVERY ====================

echo "==================== 09. BACKUP & RECOVERY ===================="
printf "\n"

# --- 9.1 BACKUP TOOLS AND SERVICES ---
echo "9.1 BACKUP TOOLS AND SERVICES"
SCHEDULER_STATE="INACTIVE"
if systemctl is-active cron >/dev/null 2>&1; then
    SCHEDULER_STATE="ACTIVE (cron)"
elif systemctl is-active crond >/dev/null 2>&1; then
    SCHEDULER_STATE="ACTIVE (crond)"
elif systemctl is-active systemd-timers.target >/dev/null 2>&1; then
    SCHEDULER_STATE="ACTIVE (systemd-timers)"
fi
echo "Scheduler Status : $SCHEDULER_STATE"
echo
echo "--- Backup Binaries / Engines Detection ---"

BACKUP_TOOLS_FOUND=0

if command -v rsync >/dev/null 2>&1; then
    printf "  %-22s : FOUND (%s)
" "rsync" "$(command -v rsync)"
    BACKUP_TOOLS_FOUND=$((BACKUP_TOOLS_FOUND + 1))
else
    printf "  %-22s : NOT FOUND
" "rsync"
fi

if command -v borg >/dev/null 2>&1; then
    printf "  %-22s : FOUND (%s)
" "borg" "$(command -v borg)"
    BACKUP_TOOLS_FOUND=$((BACKUP_TOOLS_FOUND + 1))
else
    printf "  %-22s : NOT FOUND
" "borg"
fi

if command -v restic >/dev/null 2>&1; then
    printf "  %-22s : FOUND (%s)
" "restic" "$(command -v restic)"
    BACKUP_TOOLS_FOUND=$((BACKUP_TOOLS_FOUND + 1))
else
    printf "  %-22s : NOT FOUND
" "restic"
fi

if command -v duplicity >/dev/null 2>&1; then
    printf "  %-22s : FOUND (%s)
" "duplicity" "$(command -v duplicity)"
    BACKUP_TOOLS_FOUND=$((BACKUP_TOOLS_FOUND + 1))
else
    printf "  %-22s : NOT FOUND
" "duplicity"
fi

if command -v proxmox-backup-client >/dev/null 2>&1; then
    printf "  %-22s : FOUND (%s)
" \
        "proxmox-backup-client" \
        "$(command -v proxmox-backup-client)"
    BACKUP_TOOLS_FOUND=$((BACKUP_TOOLS_FOUND + 1))
else
    printf "  %-22s : NOT FOUND
" "proxmox-backup-client"
fi
printf "\n%.0s" {1..3}

# --- 9.2 SCHEDULED BACKUP JOBS ---
echo "9.2 SCHEDULED BACKUP JOBS"
BACKUP_JOBS_FOUND=0
echo "--- systemd Backup Timers ---"
TIMERS_LIST=$(systemctl list-timers --all --no-pager 2>/dev/null | grep -Ei 'backup|borg|restic|pve|vzdump|snap')
if [ -n "$TIMERS_LIST" ]; then
    echo "$TIMERS_LIST"
    BACKUP_JOBS_FOUND=$((BACKUP_JOBS_FOUND + 1))
else
    echo "No explicit backup systemd timers found"
fi
echo
echo "--- System Crontabs & Custom Definitions ---"
CRON_TRAFFIC=$(grep -Ei 'backup|borg|restic|rsync|vzdump' /etc/crontab /etc/cron.d/* /var/spool/cron/crontabs/* 2>/dev/null)
if [ -n "$CRON_TRAFFIC" ]; then
    echo "$CRON_TRAFFIC" | head -40
    BACKUP_JOBS_FOUND=$((BACKUP_JOBS_FOUND + 1))
else
    echo "No backup jobs found in system crontabs"
fi
echo
echo "--- Global Cron Directories ---"
CRON_DIR_SCRIPTS=$(find /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly -maxdepth 1 -type f 2>/dev/null | grep -Ei 'backup|borg|restic|rsync|snap')
if [ -n "$CRON_DIR_SCRIPTS" ]; then
    echo "$CRON_DIR_SCRIPTS"
    BACKUP_JOBS_FOUND=$((BACKUP_JOBS_FOUND + 1))
else
    echo "No explicit backup scripts found in cron directories"
fi
printf "\n%.0s" {1..3}

# --- 9.3 BACKUP REPOSITORIES AND DESTINATIONS ---

echo "9.3 BACKUP REPOSITORIES AND DESTINATIONS"

echo "--- Active Backup Mountpoints ---"

TARGET_MOUNTS_FOUND=0

while IFS= read -r TARGET; do
    [ -z "$TARGET" ] && continue

    TARGET_MOUNTS_FOUND=$((TARGET_MOUNTS_FOUND + 1))

    OPTIONS=$(
        timeout 3 findmnt \
            -rn \
            -T "$TARGET" \
            -o OPTIONS \
            2>/dev/null
    )

    if echo "$OPTIONS" | grep -Eq '(^|,)ro(,|$)'; then
        echo "INFO: $TARGET is mounted read-only"
        continue
    fi

    TEST_FILE="$TARGET/.backup_write_test_$$"

    if timeout 3 touch "$TEST_FILE" 2>/dev/null && [ -f "$TEST_FILE" ]; then
        echo "OK: $TARGET is writable"
        rm -f -- "$TEST_FILE"
    else
        echo "WARNING: $TARGET is not writable or not responding"
    fi
done < <(
    timeout 5 findmnt \
        -rn \
        -t nfs,nfs4,cifs,vfat,ext4,xfs,zfs \
        -o TARGET \
        2>/dev/null | \
        grep -Ei 'backup|pve|pbs|borg|restic|usb|backup_storage'
)

if [ "$TARGET_MOUNTS_FOUND" -eq 0 ]; then
    echo "No dedicated backup mountpoints discovered"
fi

printf "\n%.0s" {1..3}

# --- 9.4 BACKUP STORAGE CAPACITY ---
echo "9.4 BACKUP STORAGE CAPACITY"
echo "--- Filesystem Capacity ---"
DF_OUTPUT=$(timeout 8 df -hT 2>/dev/null)
if [ -n "$DF_OUTPUT" ]; then
    echo "$DF_OUTPUT" | grep -Ei 'Filesystem|Type|backup|pve|pbs|borg|restic|nfs|cifs|usb' || echo "$DF_OUTPUT" | head -25
else
    echo "Filesystem capacity query unavailable or timed out"
fi
echo
echo "--- Inode Capacity ---"
DF_INODE_OUTPUT=$(timeout 8 df -ih 2>/dev/null)
if [ -n "$DF_INODE_OUTPUT" ]; then
    echo "$DF_INODE_OUTPUT" | grep -Ei 'Filesystem|Type|backup|pve|pbs|borg|restic|nfs|cifs|usb' || echo "$DF_INODE_OUTPUT" | head -25
else
    echo "Inode capacity query unavailable or timed out"
fi
printf "\n%.0s" {1..3}

# --- 9.5 RECENT BACKUP ACTIVITY ---
echo "9.5 RECENT BACKUP ACTIVITY"
BACKUP_SUCCESS_FOUND=0
if command -v journalctl >/dev/null 2>&1; then
    echo "--- Backup-related Unit Activity: Last 7 Days ---"
    journalctl -u 'borg*' -u 'restic*' -u 'vzdump*' -u 'proxmox-backup*' --since "7 days ago" --no-pager 2>/dev/null | tail -50 || echo "No backup unit activity found"
    echo
echo "--- Successful Backup Markers: Last 7 Days ---"
    LOGS_SUCCESS=$(journalctl --since "7 days ago" --no-pager 2>/dev/null | grep -Ei 'backup|borg|restic|rsync|vzdump|proxmox-backup' | grep -Ei 'success|finished|complete|completed|done|TASK OK' | tail -15)
    if [ -n "$LOGS_SUCCESS" ]; then
        echo "$LOGS_SUCCESS"
        BACKUP_SUCCESS_FOUND=1
    else
        echo "No explicit successful backup markers found"
    fi
else
    LOGS_SUCCESS=$(grep -Eih 'backup|borg|restic|rsync|vzdump' /var/log/syslog /var/log/messages 2>/dev/null | grep -Ei 'success|finish|complete|done' | tail -15)
    if [ -n "$LOGS_SUCCESS" ]; then
        echo "$LOGS_SUCCESS"
        BACKUP_SUCCESS_FOUND=1
    else
        echo "No successful backup markers found in legacy logs"
    fi
fi
printf "\n%.0s" {1..3}

# --- 9.6 BACKUP FAILURES ---
echo "9.6 BACKUP FAILURES"
if command -v journalctl >/dev/null 2>&1; then
    BACKUP_FAILURES=$(journalctl --since "7 days ago" --no-pager 2>/dev/null | grep -Ei 'backup|borg|restic|rsync|vzdump|proxmox-backup' | grep -Ei 'fail|error|abort|critical|failed with|TASK ERROR' | tail -20)
else
    BACKUP_FAILURES=$(grep -Eih 'backup|borg|restic|rsync|vzdump' /var/log/syslog /var/log/messages 2>/dev/null | grep -Ei 'fail|error|abort|critical' | tail -20)
fi
if [ -n "$BACKUP_FAILURES" ]; then
    echo "$BACKUP_FAILURES"
else
    echo "No backup failure markers found during the last 7 days"
fi
printf "\n%.0s" {1..3}

# --- 9.7 BACKUP INVENTORY AND LATEST BACKUP ---
echo "9.7 BACKUP INVENTORY AND LATEST BACKUP"
LATEST_BACKUP_MARK=$(find /var/log /backup* /mnt /opt -xdev -type f \( -iname '*backup*' -o -iname '*.bak' -o -iname '*.tgz' -o -iname '*.tar.gz' -o -iname '*.vma*' -o -iname '*.pxar' -o -iname '*.vzdump' \) -printf '%T@|%p\n' 2>/dev/null | sort -t '|' -k1,1nr | head -1)
if [ -n "$LATEST_BACKUP_MARK" ]; then
    EPOCH_TIME=${LATEST_BACKUP_MARK%%|*}
    FILE_NAME=${LATEST_BACKUP_MARK#*|}

    EPOCH_SECONDS=${EPOCH_TIME%%.*}

    case "$EPOCH_SECONDS" in
        ''|*[!0-9]*)
            EPOCH_SECONDS=0
            ;;
    esac

    CURRENT_EPOCH=$(date +%s)

    if [ "$EPOCH_SECONDS" -gt 0 ] && [ "$CURRENT_EPOCH" -ge "$EPOCH_SECONDS" ]; then
        AGE_DAYS=$(( (CURRENT_EPOCH - EPOCH_SECONDS) / 86400 ))
    else
        AGE_DAYS=999
    fi

    echo "Latest matching backup object : $FILE_NAME"
    echo "Timestamp                     : $(date -d "@$EPOCH_SECONDS" +"%Y-%m-%d %H:%M:%S" 2>/dev/null || date -r "$FILE_NAME" +"%Y-%m-%d %H:%M:%S" 2>/dev/null)"
    echo "Calculated age                : $AGE_DAYS day(s)"
else
    echo "No matching local backup objects found by filename pattern"
fi
printf "\n%.0s" {1..3}

# --- 9.8 BACKUP INTEGRITY AND VERIFICATION ---
echo "9.8 BACKUP INTEGRITY AND VERIFICATION"
echo "--- Borg Repository Inventory ---"
if command -v borg >/dev/null 2>&1; then timeout 10 borg list 2>/dev/null | head -15 || echo "Borg repository unavailable, unconfigured, or credentials missing"; else echo "Borg not installed"; fi
echo
echo "--- Restic Snapshot Inventory ---"
if command -v restic >/dev/null 2>&1; then timeout 10 restic snapshots 2>/dev/null | head -15 || echo "Restic repository unavailable, unconfigured, or credentials missing"; else echo "Restic not installed"; fi
echo
echo "--- PBS Verify Jobs ---"
if command -v proxmox-backup-manager >/dev/null 2>&1; then proxmox-backup-manager verify-job list 2>/dev/null || echo "PBS verify jobs unavailable"; else echo "Proxmox Backup Server tools not installed"; fi
echo
echo "--- Local Storage Consistency Context ---"
if command -v zpool >/dev/null 2>&1; then zpool status 2>/dev/null | grep -E 'pool:|state:|scan:|errors:' || echo "No ZFS pool status available"; fi
if [ -f /proc/mdstat ]; then grep -E 'active|inactive|recovery|resync|reshape|check|\[[U_]+\]' /proc/mdstat 2>/dev/null || cat /proc/mdstat 2>/dev/null; fi
printf "\n%.0s" {1..3}

# --- 9.9 SNAPSHOT TECHNOLOGIES ---
echo "9.9 SNAPSHOT TECHNOLOGIES"
echo "--- LVM Snapshots ---"
if command -v lvs >/dev/null 2>&1; then lvs -a 2>/dev/null | grep -Ei 'snap' || echo "No LVM snapshots detected"; else echo "LVM tools not installed"; fi
echo
echo "--- ZFS Snapshots ---"
if command -v zfs >/dev/null 2>&1; then zfs list -t snapshot 2>/dev/null | head -25 || echo "No ZFS snapshots detected"; else echo "ZFS tools not installed"; fi
echo
echo "--- Btrfs Snapshots ---"
if command -v btrfs >/dev/null 2>&1; then btrfs subvolume list -s / 2>/dev/null || echo "No Btrfs snapshots detected or root is not Btrfs"; else echo "Btrfs tools not installed"; fi
printf "\n%.0s" {1..3}

# --- 9.10 PROXMOX VE BACKUP CONFIGURATION ---
echo "9.10 PROXMOX VE BACKUP CONFIGURATION"
if [ -d /etc/pve ]; then
    echo "--- PBS Storage Definitions ---"
    grep -A 12 -E '^pbs:' /etc/pve/storage.cfg 2>/dev/null || echo "No PBS storage definitions found"
    echo
echo "--- Proxmox Storage Status ---"
    pvesm status 2>/dev/null || echo "PVE storage status unavailable"
    echo
echo "--- Scheduled Backup Jobs ---"
    if [ -f /etc/pve/jobs.cfg ]; then cat /etc/pve/jobs.cfg; elif [ -f /etc/pve/vzdump.cron ]; then cat /etc/pve/vzdump.cron; else echo "No scheduled vzdump jobs found"; fi
    echo
echo "--- Cluster Backup API ---"
    timeout 5 pvesh get /cluster/backup --output-format yaml 2>/dev/null | head -40 || echo "PVE backup API metadata unavailable"
else
    echo "Proxmox VE environment not detected"
fi
printf "\n%.0s" {1..3}

# --- 9.11 PROXMOX BACKUP SERVER ---

echo "9.11 PROXMOX BACKUP SERVER"

if command -v proxmox-backup-manager >/dev/null 2>&1; then
    echo "--- PBS Datastores ---"

    proxmox-backup-manager datastore list 2>/dev/null || \
        echo "PBS datastore information unavailable"

    echo

    echo "--- PBS Prune Jobs ---"

    proxmox-backup-manager prune-job list 2>/dev/null || \
        echo "PBS prune jobs unavailable"

    echo

    echo "--- PBS Verify Jobs ---"

    proxmox-backup-manager verify-job list 2>/dev/null || \
        echo "PBS verify jobs unavailable"

    echo

    echo "--- PBS Garbage Collection Status by Datastore ---"

    DATASTORE_NAMES=$(
        proxmox-backup-manager datastore list \
            --output-format json \
            2>/dev/null | \
        python3 -c '
import json
import sys

try:
    data = json.load(sys.stdin)
except Exception:
    sys.exit(1)

for item in data:
    name = item.get("name") or item.get("store")
    if name:
        print(name)
' 2>/dev/null
    )

    if [ -z "$DATASTORE_NAMES" ]; then
        DATASTORE_NAMES=$(
            proxmox-backup-manager datastore list \
                2>/dev/null | \
            awk '
                NR == 1 {next}
                /^[[:space:]]*$/ {next}
                $1 ~ /^[-+|]+$/ {next}
                {print $1}
            '
        )
    fi

    if [ -n "$DATASTORE_NAMES" ]; then
        while IFS= read -r DATASTORE; do
            [ -z "$DATASTORE" ] && continue

            echo "Datastore: $DATASTORE"

            proxmox-backup-manager \
                garbage-collection status "$DATASTORE" \
                2>/dev/null || \
                echo "Garbage collection status unavailable for $DATASTORE"

            echo
        done <<< "$DATASTORE_NAMES"
    else
        echo "No PBS datastores found for garbage collection status"
    fi

    echo "--- PBS Recent Tasks ---"

    proxmox-backup-manager task list 2>/dev/null | \
        head -20 || \
        echo "PBS task history unavailable"
else
    echo "Proxmox Backup Server tools not detected"
fi

printf "\n%.0s" {1..3}

# --- 9.12 RECOVERY READINESS ---
echo "9.12 RECOVERY READINESS"
RECOVERY_VALID=1
if [ "$BACKUP_TOOLS_FOUND" -eq 0 ] && [ ! -d /etc/pve ] && ! command -v proxmox-backup-manager >/dev/null 2>&1; then
    echo "CRITICAL: No backup tools or Proxmox backup stack detected"
    RECOVERY_VALID=0
else
    echo "OK: Backup tooling or platform backup stack detected"
fi
if [ -n "$LATEST_BACKUP_MARK" ]; then
    if [ "${AGE_DAYS:-999}" -le 7 ]; then echo "OK: Latest matching backup object is $AGE_DAYS day(s) old"; else echo "WARNING: Latest matching backup object is $AGE_DAYS day(s) old"; RECOVERY_VALID=0; fi
else
    echo "WARNING: No local backup object detected by filename pattern"
    RECOVERY_VALID=0
fi
if [ "$BACKUP_SUCCESS_FOUND" -eq 1 ]; then echo "OK: At least one successful backup marker found in the last 7 days"; else echo "WARNING: No explicit successful backup marker found in the last 7 days"; fi
echo
echo "--- Root Filesystem Headroom ---"
df -h / 2>/dev/null || echo "Root filesystem capacity unavailable"
printf "\n%.0s" {1..3}

# --- 9.13 BACKUP SUMMARY ---
echo "9.13 BACKUP SUMMARY"
echo "--- Backup and Recovery Summary ---"
echo "Scheduler................$SCHEDULER_STATE"
if [ "$BACKUP_TOOLS_FOUND" -gt 0 ]; then echo "Backup Tool..............FOUND ($BACKUP_TOOLS_FOUND installed tool(s))"; else echo "Backup Tool..............NOT FOUND"; fi
if [ "$BACKUP_JOBS_FOUND" -gt 0 ]; then echo "Backup Job...............FOUND"; else echo "Backup Job...............NOT FOUND"; fi
if [ "$TARGET_MOUNTS_FOUND" -gt 0 ]; then echo "Repository...............FOUND / MOUNTED"; else echo "Repository...............NOT FOUND BY MOUNTPOINT PATTERN"; fi
if [ -n "$LATEST_BACKUP_MARK" ]; then LAST_BACKUP_DATE=$(date -d "@$EPOCH_SECONDS" +"%Y-%m-%d" 2>/dev/null || date -r "$FILE_NAME" +"%Y-%m-%d" 2>/dev/null); echo "Last Backup Match........${LAST_BACKUP_DATE:-UNKNOWN} ($AGE_DAYS day(s) ago)"; else echo "Last Backup Match........NOT DETECTED"; fi
if [ "$BACKUP_SUCCESS_FOUND" -eq 1 ]; then echo "Recent Success Marker....FOUND"; else echo "Recent Success Marker....NOT FOUND"; fi
if [ "$RECOVERY_VALID" -eq 1 ]; then echo "Recovery Readiness.......OK"; else echo "Recovery Readiness.......WARNING"; fi