def not_enough_space_upgrade(): backup_size, free_before, free_after = can_perform_backup() if free_after / 1000000 < 50: flash( "A backup must be performed during an upgrade and there is " "not enough free space to perform a backup. A backup " "requires {size_bu:.1f} MB but there is only {size_free:.1f} " "MB available, which would leave {size_after:.1f} MB after " "the backup. If the free space after a backup is less than 50" " MB, the backup cannot proceed. Free up space by deleting " "current backups.".format(size_bu=backup_size / 1000000, size_free=free_before / 1000000, size_after=free_after / 1000000), 'error') return True else: return False
def not_enough_space_upgrade(): backup_size, free_before, free_after = can_perform_backup() if free_after / 1000000 < 50: flash( "A backup must be performed during an upgrade and there is " "not enough free space to perform a backup. A backup " "requires {size_bu:.1f} MB but there is only {size_free:.1f} " "MB available, which would leave {size_after:.1f} MB after " "the backup. If the free space after a backup is less than 50" " MB, the backup cannot proceed. Free up space by deleting " "current backups.".format(size_bu=backup_size / 1000000, size_free=free_before / 1000000, size_after=free_after / 1000000), 'error') return True else: return False
def admin_backup(): """ Load the backup management page """ if not utils_general.user_has_permission('edit_settings'): return redirect(url_for('routes_general.home')) form_backup = forms_misc.Backup() backup_dirs_tmp = [] if not os.path.isdir('/var/Mycodo-backups'): flash("Error: Backup directory doesn't exist.", "error") else: backup_dirs_tmp = sorted(next(os.walk(BACKUP_PATH))[1]) backup_dirs_tmp.reverse() backup_dirs = [] full_paths = [] for each_dir in backup_dirs_tmp: if each_dir.startswith("Mycodo-backup-"): full_path = os.path.join(BACKUP_PATH, each_dir) backup_dirs.append( (each_dir, get_directory_size(full_path) / 1000000.0)) full_paths.append(full_path) if request.method == 'POST': if form_backup.backup.data: backup_size, free_before, free_after = can_perform_backup() if free_after / 1000000 > 50: cmd = "{pth}/mycodo/scripts/mycodo_wrapper backup-create" \ " | ts '[%Y-%m-%d %H:%M:%S]'" \ " >> {log} 2>&1".format(pth=INSTALL_DIRECTORY, log=BACKUP_LOG_FILE) subprocess.Popen(cmd, shell=True) flash(gettext("Backup in progress"), "success") else: flash( "Not enough free space to perform a backup. A backup " "requires {size_bu:.1f} MB but there is only " "{size_free:.1f} MB available, which would leave " "{size_after:.1f} MB after the backup. If the free space " "after a backup is less than 50 MB, the backup cannot " "proceed. Free up space by deleting current " "backups.".format(size_bu=backup_size / 1000000, size_free=free_before / 1000000, size_after=free_after / 1000000), 'error') elif form_backup.delete.data: cmd = "{pth}/mycodo/scripts/mycodo_wrapper backup-delete {dir}" \ " 2>&1".format(pth=INSTALL_DIRECTORY, dir=form_backup.selected_dir.data) subprocess.Popen(cmd, shell=True) flash(gettext("Deletion of backup in progress"), "success") elif form_backup.restore.data: cmd = "{pth}/mycodo/scripts/mycodo_wrapper backup-restore {backup}" \ " | ts '[%Y-%m-%d %H:%M:%S]'" \ " >> {log} 2>&1".format(pth=INSTALL_DIRECTORY, backup=form_backup.full_path.data, log=RESTORE_LOG_FILE) subprocess.Popen(cmd, shell=True) flash(gettext("Restore in progress"), "success") return render_template('admin/backup.html', form_backup=form_backup, backup_dirs=backup_dirs, full_paths=full_paths)
def admin_backup(): """ Load the backup management page """ if not utils_general.user_has_permission('edit_settings'): return redirect(url_for('routes_general.home')) form_backup = forms_misc.Backup() backup_dirs_tmp = [] if not os.path.isdir('/var/Mycodo-backups'): flash("Error: Backup directory doesn't exist.", "error") else: backup_dirs_tmp = sorted(next(os.walk(BACKUP_PATH))[1]) backup_dirs_tmp.reverse() backup_dirs = [] full_paths = [] for each_dir in backup_dirs_tmp: if each_dir.startswith("Mycodo-backup-"): full_path = os.path.join(BACKUP_PATH, each_dir) backup_dirs.append((each_dir, get_directory_size(full_path) / 1000000.0)) full_paths.append(full_path) if request.method == 'POST': if form_backup.backup.data: backup_size, free_before, free_after = can_perform_backup() if free_after / 1000000 > 50: cmd = "{pth}/mycodo/scripts/mycodo_wrapper backup-create" \ " | ts '[%Y-%m-%d %H:%M:%S]'" \ " >> {log} 2>&1".format(pth=INSTALL_DIRECTORY, log=BACKUP_LOG_FILE) subprocess.Popen(cmd, shell=True) flash(gettext("Backup in progress"), "success") else: flash( "Not enough free space to perform a backup. A backup " "requires {size_bu:.1f} MB but there is only " "{size_free:.1f} MB available, which would leave " "{size_after:.1f} MB after the backup. If the free space " "after a backup is less than 50 MB, the backup cannot " "proceed. Free up space by deleting current " "backups.".format(size_bu=backup_size / 1000000, size_free=free_before / 1000000, size_after=free_after / 1000000), 'error') elif form_backup.download.data: def get_all_file_paths(directory): file_paths = [] for root, directories, files in os.walk(directory): for filename in files: # join the two strings in order to form the full filepath filepath = os.path.join(root, filename) file_paths.append(filepath) return file_paths try: backup_date_version = form_backup.selected_dir.data download_dir = os.path.join(BACKUP_PATH, 'Mycodo-backup-{}'.format(backup_date_version)) save_file = "Mycodo_Backup_{dv}_{host}_.zip".format( dv=backup_date_version, host=socket.gethostname().replace(' ', '')) file_paths = get_all_file_paths(download_dir) string_remove = "{}".format(os.path.join(BACKUP_PATH, download_dir)) if not os.path.isdir(download_dir): flash("Directory not found: {}".format(download_dir), "error") else: # Zip all files in the_backup directory data = io.BytesIO() with zipfile.ZipFile(data, 'w') as zip: # writing each file one by one for file in file_paths: # Remove first two directory names from zip file, so the Mycodo root is the zip root zip.write(file, file.replace(string_remove, "")) data.seek(0) # Send zip file to user return send_file( data, mimetype='application/zip', as_attachment=True, attachment_filename=save_file ) except Exception as err: flash("Error: {}".format(err), "error") elif form_backup.delete.data: cmd = "{pth}/mycodo/scripts/mycodo_wrapper backup-delete {dir}" \ " 2>&1".format(pth=INSTALL_DIRECTORY, dir=form_backup.selected_dir.data) subprocess.Popen(cmd, shell=True) flash(gettext("Deletion of backup in progress"), "success") elif form_backup.restore.data: cmd = "{pth}/mycodo/scripts/mycodo_wrapper backup-restore {backup}" \ " | ts '[%Y-%m-%d %H:%M:%S]'" \ " >> {log} 2>&1".format(pth=INSTALL_DIRECTORY, backup=form_backup.full_path.data, log=RESTORE_LOG_FILE) subprocess.Popen(cmd, shell=True) flash(gettext("Restore in progress"), "success") return render_template('admin/backup.html', form_backup=form_backup, backup_dirs=backup_dirs, full_paths=full_paths)
def admin_backup(): """ Load the backup management page """ if not utils_general.user_has_permission('edit_settings'): return redirect(url_for('routes_general.home')) form_backup = forms_misc.Backup() backup_dirs_tmp = [] if not os.path.isdir('/var/Mycodo-backups'): flash("Error: Backup directory doesn't exist.", "error") else: backup_dirs_tmp = sorted(next(os.walk(BACKUP_PATH))[1]) backup_dirs_tmp.reverse() backup_dirs = [] full_paths = [] for each_dir in backup_dirs_tmp: if each_dir.startswith("Mycodo-backup-"): full_path = os.path.join(BACKUP_PATH, each_dir) backup_dirs.append((each_dir, get_directory_size(full_path) / 1000000.0)) full_paths.append(full_path) if request.method == 'POST': if form_backup.backup.data: backup_size, free_before, free_after = can_perform_backup() if free_after / 1000000 > 50: cmd = "{pth}/mycodo/scripts/mycodo_wrapper backup-create" \ " | ts '[%Y-%m-%d %H:%M:%S]'" \ " >> {log} 2>&1".format(pth=INSTALL_DIRECTORY, log=BACKUP_LOG_FILE) subprocess.Popen(cmd, shell=True) flash(gettext("Backup in progress"), "success") else: flash( "Not enough free space to perform a backup. A backup " "requires {size_bu:.1f} MB but there is only " "{size_free:.1f} MB available, which would leave " "{size_after:.1f} MB after the backup. If the free space " "after a backup is less than 50 MB, the backup cannot " "proceed. Free up space by deleting current " "backups.".format(size_bu=backup_size / 1000000, size_free=free_before / 1000000, size_after=free_after / 1000000), 'error') elif form_backup.delete.data: cmd = "{pth}/mycodo/scripts/mycodo_wrapper backup-delete {dir}" \ " 2>&1".format(pth=INSTALL_DIRECTORY, dir=form_backup.selected_dir.data) subprocess.Popen(cmd, shell=True) flash(gettext("Deletion of backup in progress"), "success") elif form_backup.restore.data: cmd = "{pth}/mycodo/scripts/mycodo_wrapper backup-restore {backup}" \ " | ts '[%Y-%m-%d %H:%M:%S]'" \ " >> {log} 2>&1".format(pth=INSTALL_DIRECTORY, backup=form_backup.full_path.data, log=RESTORE_LOG_FILE) subprocess.Popen(cmd, shell=True) flash(gettext("Restore in progress"), "success") return render_template('admin/backup.html', form_backup=form_backup, backup_dirs=backup_dirs, full_paths=full_paths)
def admin_upgrade(): """ Display any available upgrades and option to upgrade """ if not utils_general.user_has_permission('edit_settings'): return redirect(url_for('routes_general.home')) if not internet(): flash(gettext("Upgrade functionality is disabled because an internet " "connection was unable to be detected"), "error") return render_template('admin/upgrade.html', is_internet=False) # Read from the upgrade status file created by the upgrade script # to indicate if the upgrade is running. try: with open(UPGRADE_INIT_FILE) as f: upgrade = int(f.read(1)) except IOError: try: with open(UPGRADE_INIT_FILE, 'w') as f: f.write('0') finally: upgrade = 0 if upgrade: if upgrade == 2: flash(gettext("There was an error encountered during the upgrade" " process. Check the upgrade log for details."), "error") return render_template('admin/upgrade.html', upgrade=upgrade) form_backup = forms_misc.Backup() form_upgrade = forms_misc.Upgrade() is_internet = True upgrade_available = False # Check for any new Mycodo releases on github releases = [] try: maj_version = int(MYCODO_VERSION.split('.')[0]) releases = github_releases(maj_version) except Exception as err: flash(gettext("Could not determine local mycodo version or " "online release versions: {err}".format(err=err)), "error") if len(releases): latest_release = releases[0] current_releases = [] releases_behind = None for index, each_release in enumerate(releases): if parse_version(each_release) >= parse_version(MYCODO_VERSION): current_releases.append(each_release) if parse_version(each_release) == parse_version(MYCODO_VERSION): releases_behind = index if parse_version(releases[0]) > parse_version(MYCODO_VERSION): upgrade_available = True else: current_releases = [] latest_release = '0.0.0' releases_behind = 0 # Update database to reflect the current upgrade status mod_misc = Misc.query.first() if mod_misc.mycodo_upgrade_available != upgrade_available: mod_misc.mycodo_upgrade_available = upgrade_available db.session.commit() if request.method == 'POST': if (form_upgrade.upgrade.data and (upgrade_available or FORCE_UPGRADE_MASTER)): backup_size, free_before, free_after = can_perform_backup() if free_after / 1000000 < 50: flash( "A backup must be performed during an upgrade and there " "is not enough free space to perform a backup. A backup " "requires {size_bu:.1f} MB but there is only " "{size_free:.1f} MB available, which would leave " "{size_after:.1f} MB after the backup. If the free space " "after a backup is less than 50 MB, the backup cannot " "proceed. Free up space by deleting current " "backups.".format(size_bu=backup_size / 1000000, size_free=free_before / 1000000, size_after=free_after / 1000000), 'error') elif FORCE_UPGRADE_MASTER: cmd = "{pth}/mycodo/scripts/mycodo_wrapper upgrade-master" \ " | ts '[%Y-%m-%d %H:%M:%S]'" \ " >> {log} 2>&1".format(pth=INSTALL_DIRECTORY, log=UPGRADE_LOG_FILE) subprocess.Popen(cmd, shell=True) upgrade = 1 flash(gettext("The upgrade (from master branch) has started"), "success") else: cmd = "{pth}/mycodo/scripts/mycodo_wrapper upgrade" \ " | ts '[%Y-%m-%d %H:%M:%S]'" \ " >> {log} 2>&1".format(pth=INSTALL_DIRECTORY, log=UPGRADE_LOG_FILE) subprocess.Popen(cmd, shell=True) upgrade = 1 mod_misc = Misc.query.first() mod_misc.mycodo_upgrade_available = False db.session.commit() flash(gettext("The upgrade has started"), "success") else: flash(gettext("You cannot upgrade if an upgrade is not available"), "error") return render_template('admin/upgrade.html', force_upgrade_master=FORCE_UPGRADE_MASTER, form_backup=form_backup, form_upgrade=form_upgrade, current_release=MYCODO_VERSION, current_releases=current_releases, latest_release=latest_release, releases_behind=releases_behind, upgrade_available=upgrade_available, upgrade=upgrade, is_internet=is_internet)