diff --git a/omv_backups_v3.py b/omv_backups_v3.py index ba5becd..bd84797 100644 --- a/omv_backups_v3.py +++ b/omv_backups_v3.py @@ -43,7 +43,7 @@ except getopt.GetoptError as err: output = None # QJ : getopts _MODE = "manual" -_FIRST = _TEST = False +_FIRST = _TEST = _RESTORE = _BACKUP = False _EXECUTE = True for o, a in opts: if o == "-a": @@ -54,6 +54,10 @@ for o, a in opts: _FIRST = True elif o in ("-t", "--test"): _TEST = True + elif o in ("-r", "--restore"): + _RESTORE = True + elif o in ("-b", "--backup"): + _BACKUP = True elif o in ("-d", "--dry"): _EXECUTE = False client = mqtt_client.Client() @@ -135,119 +139,238 @@ while not is_port_open(BACKUP_HOST, port): n += 1 print(f"Port {port} on {BACKUP_HOST} is open.") +if _RESTORE: + for b in backups[host]: + topic = "sectorq/omv/backups/{}".format(b.lower()) + if not backups[host][b]["active"]: + print("Backup {} is not active!".format(b)) + client.connect(broker,1883,60) + msg = {"status":"inactive","bak_name":b,"start_time":"inactive","end_time":"inactive","progress":0} -for b in backups[host]: - topic = "sectorq/omv/backups/{}".format(b.lower()) - if not backups[host][b]["active"]: - print("Backup {} is not active!".format(b)) + client.publish(topic, json.dumps(msg)) + client.disconnect() + continue + + SOURCE_DIR = backups[host][b]["source"] + now = datetime.datetime.now() + BACKUP_HOST = "root@omv.home.lan" + BACKUP_DEVICE = "/srv/dev-disk-by-uuid-2f843500-95b6-43b0-bea1-9b67032989b8" + BACKUP_DIR = f"/backup/{host}/{b}" + NEW_BACKUP_DIR = f"{BACKUP_DEVICE}/backup/{host}/{b}" + DATETIME = now.strftime("%Y-%m-%d_%H-%M-%S") + if _FIRST: + BACKUP_PATH="{}/initial".format(BACKUP_DIR) + else: + BACKUP_PATH="{}/{}".format(BACKUP_DIR, DATETIME) + LATEST_LINK="{}/latest".format(BACKUP_DIR) + FULL_BACKUP_LATEST = f"{NEW_BACKUP_DIR}/latest" + LATEST_LINK = f"/{host}/{b}/latest" + + + msg = {"status":"started","bak_name":b,"start_time":DATETIME,"end_time":"in progress", "progress":0} client.connect(broker,1883,60) - msg = {"status":"inactive","bak_name":b,"start_time":"inactive","end_time":"inactive","progress":0} - client.publish(topic, json.dumps(msg)) client.disconnect() - continue - SOURCE_DIR = backups[host][b]["source"] - now = datetime.datetime.now() - BACKUP_HOST = "root@omv.home.lan" - BACKUP_DEVICE = "/srv/dev-disk-by-uuid-2f843500-95b6-43b0-bea1-9b67032989b8" - BACKUP_DIR = f"/backup/{host}/{b}" - NEW_BACKUP_DIR = f"{BACKUP_DEVICE}/backup/{host}/{b}" - DATETIME = now.strftime("%Y-%m-%d_%H-%M-%S") - if _FIRST: - BACKUP_PATH="{}/initial".format(BACKUP_DIR) - else: - BACKUP_PATH="{}/{}".format(BACKUP_DIR, DATETIME) - LATEST_LINK="{}/latest".format(BACKUP_DIR) - FULL_BACKUP_LATEST = f"{NEW_BACKUP_DIR}/latest" - LATEST_LINK = f"/{host}/{b}/latest" + cmnd = "ssh root@omv.home.lan 'mkdir -p " + NEW_BACKUP_DIR + "'" + + if _EXECUTE: + status, output = subprocess.getstatusoutput(cmnd) + print("Create backup dir") + print(cmnd) - msg = {"status":"started","bak_name":b,"start_time":DATETIME,"end_time":"in progress", "progress":0} - client.connect(broker,1883,60) - client.publish(topic, json.dumps(msg)) - client.disconnect() + #cmnd = "rsync -av --delete {}/ --link-dest {} --exclude=\".cache\" {}".format(SOURCE_DIR, LATEST_LINK, BACKUP_PATH) + if _FIRST: + cmnd = f"rsync -avz --delete rsync://{BACKUP_HOST}{BACKUP_PATH} {SOURCE_DIR}" + else: + cmnd = f"rsync -avz --delete {SOURCE_DIR} --link-dest {LATEST_LINK} --exclude=\"gitlab/logs/prometheus\" --exclude=\"home-assistant.log\" --exclude=\"gitlab/logs/*\" --exclude=\"esphome/config/.esphome\" --exclude=\".cache\" --exclude=\".git\" --exclude=\"var_lib_motioneye\" rsync://{BACKUP_HOST}{BACKUP_PATH}" - cmnd = "ssh root@omv.home.lan 'mkdir -p " + NEW_BACKUP_DIR + "'" + ans = "y" + print(cmnd) + print("Sync files") + if _TEST: + + + ans = input("continue?") or "n" + if ans == "y" and _EXECUTE: - if _EXECUTE: - status, output = subprocess.getstatusoutput(cmnd) - print("Create backup dir") - print(cmnd) + # rsync --info=progress2 -avz --delete /share/docker_data/ --link-dest /m-server/docker_data/latest --exclude="gitlab/data/" --exclude="esphome/config/.esphome" --exclude="gitlab/logs/prometheus" --exclude=".cache" --exclude=".git" --exclude="var_lib_motioneye" /m-server/m-server/docker_data/newone1 - #cmnd = "rsync -av --delete {}/ --link-dest {} --exclude=\".cache\" {}".format(SOURCE_DIR, LATEST_LINK, BACKUP_PATH) - if _FIRST: - cmnd = f"rsync -avz --delete {SOURCE_DIR} --exclude=\"gitlab/logs/prometheus\" --exclude=\"home-assistant.log\" --exclude=\"gitlab/logs/*\" --exclude=\"esphome/config/.esphome\" --exclude=\".cache\" --exclude=\".git\" --exclude=\"var_lib_motioneye\" rsync://{BACKUP_HOST}{BACKUP_PATH}" - else: - cmnd = f"rsync -avz --delete {SOURCE_DIR} --link-dest {LATEST_LINK} --exclude=\"gitlab/logs/prometheus\" --exclude=\"home-assistant.log\" --exclude=\"gitlab/logs/*\" --exclude=\"esphome/config/.esphome\" --exclude=\".cache\" --exclude=\".git\" --exclude=\"var_lib_motioneye\" rsync://{BACKUP_HOST}{BACKUP_PATH}" + # input("????") - ans = "y" - print(cmnd) - print("Sync files") - if _TEST: + status, output = subprocess.getstatusoutput(cmnd) + cmnd = f"ssh root@omv.home.lan 'rm -rf {FULL_BACKUP_LATEST}'" - ans = input("continue?") or "n" - if ans == "y" and _EXECUTE: - - # rsync --info=progress2 -avz --delete /share/docker_data/ --link-dest /m-server/docker_data/latest --exclude="gitlab/data/" --exclude="esphome/config/.esphome" --exclude="gitlab/logs/prometheus" --exclude=".cache" --exclude=".git" --exclude="var_lib_motioneye" /m-server/m-server/docker_data/newone1 + #print(cmnd) + print("Removing latest link") + # input("????") + if _EXECUTE: + status, output = subprocess.getstatusoutput(cmnd) + if _FIRST: + cmnd = f"ssh root@omv.home.lan 'cd {NEW_BACKUP_DIR}; ln -s initial latest'" + else: + cmnd = f"ssh root@omv.home.lan 'cd {NEW_BACKUP_DIR}; ln -s {DATETIME} latest'" + print("Creating new latest link") + #print(cmnd) + # input("????") + if _EXECUTE: + status, output = subprocess.getstatusoutput(cmnd) -# input("????") + #Remove old + print("Removing old dirs") + # input("????") + #cmnd = "find {} -maxdepth 1 -type d -mtime +30 -exec rm -rf {{}} \;".format(BACKUP_DIR) + cmnd = f"cd {NEW_BACKUP_DIR} find ./ -maxdepth 1 -type d -mmin +30 -exec rm -rf {{}} \\;" + #print(cmnd) + # input("????") + if _EXECUTE: + status, output = subprocess.getstatusoutput(cmnd) + now = datetime.datetime.now() + ENDTIME = now.strftime("%Y-%m-%d_%H:%M:%S") + msg = {"status":"finished","bak_name":b,"start_time":DATETIME,"end_time":ENDTIME,"progress":0} + client.connect(broker,1883,10) + client.publish(topic, json.dumps(msg)) + client.disconnect() - status, output = subprocess.getstatusoutput(cmnd) - - cmnd = f"ssh root@omv.home.lan 'rm -rf {FULL_BACKUP_LATEST}'" - - #print(cmnd) - print("Removing latest link") -# input("????") - if _EXECUTE: - status, output = subprocess.getstatusoutput(cmnd) - if _FIRST: - cmnd = f"ssh root@omv.home.lan 'cd {NEW_BACKUP_DIR}; ln -s initial latest'" - else: - cmnd = f"ssh root@omv.home.lan 'cd {NEW_BACKUP_DIR}; ln -s {DATETIME} latest'" - print("Creating new latest link") - #print(cmnd) -# input("????") - if _EXECUTE: - status, output = subprocess.getstatusoutput(cmnd) - - - #Remove old - print("Removing old dirs") -# input("????") - #cmnd = "find {} -maxdepth 1 -type d -mtime +30 -exec rm -rf {{}} \;".format(BACKUP_DIR) - cmnd = f"cd {NEW_BACKUP_DIR} find ./ -maxdepth 1 -type d -mmin +30 -exec rm -rf {{}} \\;" - #print(cmnd) -# input("????") - if _EXECUTE: - status, output = subprocess.getstatusoutput(cmnd) - now = datetime.datetime.now() - ENDTIME = now.strftime("%Y-%m-%d_%H:%M:%S") - msg = {"status":"finished","bak_name":b,"start_time":DATETIME,"end_time":ENDTIME,"progress":0} - client.connect(broker,1883,10) - client.publish(topic, json.dumps(msg)) - client.disconnect() - -print("Getting size of FS") -#cmnd = "du -h --max-depth=0 {}".format(BACKUP_FS) -cmnd = "ssh root@omv.home.lan 'df -h /srv/dev-disk-by-uuid-2f843500-95b6-43b0-bea1-9b67032989b8|awk '\\''{ print $3 }'\\''|tail -1'" -print(cmnd) -status, output = subprocess.getstatusoutput(cmnd) -used_space = (output.split())[0] -now = datetime.datetime.now() -ENDJOB = now.strftime("%Y-%m-%d_%H:%M:%S") -print("Size : {}".format(used_space)) -print("Sending finished status") -msg = {"mode":_MODE,"status":"finished","bak_name":"complete","start_time":STARTTIME,"end_time":ENDJOB,"progress":0,"used_space":used_space} -print(msg) -client.connect(broker,1883,10) -client.publish(topic_sum, json.dumps(msg)) -client.disconnect() - -if _MODE == "auto": - cmnd = "ssh root@omv.home.lan 'systemctl suspend &'" + print("Getting size of FS") + #cmnd = "du -h --max-depth=0 {}".format(BACKUP_FS) + cmnd = "ssh root@omv.home.lan 'df -h /srv/dev-disk-by-uuid-2f843500-95b6-43b0-bea1-9b67032989b8|awk '\\''{ print $3 }'\\''|tail -1'" + print(cmnd) status, output = subprocess.getstatusoutput(cmnd) + used_space = (output.split())[0] + now = datetime.datetime.now() + ENDJOB = now.strftime("%Y-%m-%d_%H:%M:%S") + print("Size : {}".format(used_space)) + print("Sending finished status") + msg = {"mode":_MODE,"status":"finished","bak_name":"complete","start_time":STARTTIME,"end_time":ENDJOB,"progress":0,"used_space":used_space} + print(msg) + client.connect(broker,1883,10) + client.publish(topic_sum, json.dumps(msg)) + client.disconnect() + + if _MODE == "auto": + cmnd = "ssh root@omv.home.lan 'systemctl suspend &'" + status, output = subprocess.getstatusoutput(cmnd) + + + +if _BACKUP: + for b in backups[host]: + topic = "sectorq/omv/backups/{}".format(b.lower()) + if not backups[host][b]["active"]: + print("Backup {} is not active!".format(b)) + client.connect(broker,1883,60) + msg = {"status":"inactive","bak_name":b,"start_time":"inactive","end_time":"inactive","progress":0} + + client.publish(topic, json.dumps(msg)) + client.disconnect() + continue + + SOURCE_DIR = backups[host][b]["source"] + now = datetime.datetime.now() + BACKUP_HOST = "root@omv.home.lan" + BACKUP_DEVICE = "/srv/dev-disk-by-uuid-2f843500-95b6-43b0-bea1-9b67032989b8" + BACKUP_DIR = f"/backup/{host}/{b}" + NEW_BACKUP_DIR = f"{BACKUP_DEVICE}/backup/{host}/{b}" + DATETIME = now.strftime("%Y-%m-%d_%H-%M-%S") + if _FIRST: + BACKUP_PATH="{}/initial".format(BACKUP_DIR) + else: + BACKUP_PATH="{}/{}".format(BACKUP_DIR, DATETIME) + LATEST_LINK="{}/latest".format(BACKUP_DIR) + FULL_BACKUP_LATEST = f"{NEW_BACKUP_DIR}/latest" + LATEST_LINK = f"/{host}/{b}/latest" + + + msg = {"status":"started","bak_name":b,"start_time":DATETIME,"end_time":"in progress", "progress":0} + client.connect(broker,1883,60) + client.publish(topic, json.dumps(msg)) + client.disconnect() + + cmnd = "ssh root@omv.home.lan 'mkdir -p " + NEW_BACKUP_DIR + "'" + + if _EXECUTE: + status, output = subprocess.getstatusoutput(cmnd) + print("Create backup dir") + print(cmnd) + + + #cmnd = "rsync -av --delete {}/ --link-dest {} --exclude=\".cache\" {}".format(SOURCE_DIR, LATEST_LINK, BACKUP_PATH) + if _FIRST: + cmnd = f"rsync -avz --delete {SOURCE_DIR} --exclude=\"gitlab/logs/prometheus\" --exclude=\"home-assistant.log\" --exclude=\"gitlab/logs/*\" --exclude=\"esphome/config/.esphome\" --exclude=\".cache\" --exclude=\".git\" --exclude=\"var_lib_motioneye\" rsync://{BACKUP_HOST}{BACKUP_PATH}" + else: + cmnd = f"rsync -avz --delete {SOURCE_DIR} --link-dest {LATEST_LINK} --exclude=\"gitlab/logs/prometheus\" --exclude=\"home-assistant.log\" --exclude=\"gitlab/logs/*\" --exclude=\"esphome/config/.esphome\" --exclude=\".cache\" --exclude=\".git\" --exclude=\"var_lib_motioneye\" rsync://{BACKUP_HOST}{BACKUP_PATH}" + + ans = "y" + print(cmnd) + print("Sync files") + if _TEST: + + + ans = input("continue?") or "n" + if ans == "y" and _EXECUTE: + + # rsync --info=progress2 -avz --delete /share/docker_data/ --link-dest /m-server/docker_data/latest --exclude="gitlab/data/" --exclude="esphome/config/.esphome" --exclude="gitlab/logs/prometheus" --exclude=".cache" --exclude=".git" --exclude="var_lib_motioneye" /m-server/m-server/docker_data/newone1 + + + # input("????") + + status, output = subprocess.getstatusoutput(cmnd) + + cmnd = f"ssh root@omv.home.lan 'rm -rf {FULL_BACKUP_LATEST}'" + + #print(cmnd) + print("Removing latest link") + # input("????") + if _EXECUTE: + status, output = subprocess.getstatusoutput(cmnd) + if _FIRST: + cmnd = f"ssh root@omv.home.lan 'cd {NEW_BACKUP_DIR}; ln -s initial latest'" + else: + cmnd = f"ssh root@omv.home.lan 'cd {NEW_BACKUP_DIR}; ln -s {DATETIME} latest'" + print("Creating new latest link") + #print(cmnd) + # input("????") + if _EXECUTE: + status, output = subprocess.getstatusoutput(cmnd) + + + #Remove old + print("Removing old dirs") + # input("????") + #cmnd = "find {} -maxdepth 1 -type d -mtime +30 -exec rm -rf {{}} \;".format(BACKUP_DIR) + cmnd = f"cd {NEW_BACKUP_DIR} find ./ -maxdepth 1 -type d -mmin +30 -exec rm -rf {{}} \\;" + #print(cmnd) + # input("????") + if _EXECUTE: + status, output = subprocess.getstatusoutput(cmnd) + now = datetime.datetime.now() + ENDTIME = now.strftime("%Y-%m-%d_%H:%M:%S") + msg = {"status":"finished","bak_name":b,"start_time":DATETIME,"end_time":ENDTIME,"progress":0} + client.connect(broker,1883,10) + client.publish(topic, json.dumps(msg)) + client.disconnect() + + print("Getting size of FS") + #cmnd = "du -h --max-depth=0 {}".format(BACKUP_FS) + cmnd = "ssh root@omv.home.lan 'df -h /srv/dev-disk-by-uuid-2f843500-95b6-43b0-bea1-9b67032989b8|awk '\\''{ print $3 }'\\''|tail -1'" + print(cmnd) + status, output = subprocess.getstatusoutput(cmnd) + used_space = (output.split())[0] + now = datetime.datetime.now() + ENDJOB = now.strftime("%Y-%m-%d_%H:%M:%S") + print("Size : {}".format(used_space)) + print("Sending finished status") + msg = {"mode":_MODE,"status":"finished","bak_name":"complete","start_time":STARTTIME,"end_time":ENDJOB,"progress":0,"used_space":used_space} + print(msg) + client.connect(broker,1883,10) + client.publish(topic_sum, json.dumps(msg)) + client.disconnect() + + if _MODE == "auto": + cmnd = "ssh root@omv.home.lan 'systemctl suspend &'" + status, output = subprocess.getstatusoutput(cmnd)