Skip to content

Instantly share code, notes, and snippets.

@calvinbui
Last active October 20, 2022 14:04
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save calvinbui/913bb4726334e1461c0616cc3248aa9d to your computer and use it in GitHub Desktop.
Save calvinbui/913bb4726334e1461c0616cc3248aa9d to your computer and use it in GitHub Desktop.
FreeNAS Replication Details
"""
FreeNAS Replication status
"""
import os
import time
import sys
from datetime import datetime, timedelta
def bytes_to_gb(filesize):
return filesize / 1024 / 1024 / 1024
def bytes_to_mb(filesize):
return filesize / 1024 / 1024
def progress_bar(value, endvalue, bar_length=20):
percent = value / endvalue
arrow = '-' * int(round(percent * bar_length)-1) + '>'
spaces = ' ' * (bar_length - len(arrow))
print("\rPercent : [{0}] {1}%".format(arrow + spaces, int(round(percent * 100))))
def readable_strftime(date):
return date.strftime('%A, %d %b %y at %I:%M%p')
def get_start_datetime_from_ps(ps_output):
day_of_week = ps_output[0]
month = ps_output[1]
day_of_month = ps_output[2]
time = ps_output[3]
year = ps_output[4]
start_date_list = [day_of_week, month, day_of_month, time, year]
start_date = ' '.join([str(x) for x in start_date_list])
return datetime.strptime(start_date, '%a %b %d %X %Y')
def readable_time_diff(older, newer):
time_diff = newer - older
days = time_diff.days
hours = time_diff.seconds/3600
mins = time_diff.seconds%3600/60
secs = time_diff.seconds%3600%60
return "{} days, {} hours, {} minutes, {} seconds".format(days, int(hours), int(mins), int(secs))
def calculate_speed(remaining_size, before_remaining, refresh_time):
downloaded_inbetween_refresh = before_remaining - remaining_size
return downloaded_inbetween_refresh / refresh_time
def transfer_time(remaining_size_mb, speed, start_time):
now = datetime.now()
remaining_seconds = remaining_size_mb / speed
end_time = datetime.now() + timedelta(seconds=remaining_seconds)
print("Started : " + readable_strftime(start_time))
print("Elapsed : " + readable_time_diff(start_time, now))
print("Remaining : " + readable_time_diff(now, end_time))
print("Total : " + readable_time_diff(start_time, end_time))
print("End : " + readable_strftime(end_time))
def progress(snapshot, transferred_size, total_size, unit):
print("Snapshot : " + snapshot)
print("Transferred : {0} {2} of {1} {2}".format(round(transferred_size, 2), round(total_size, 2), unit))
print("Remaining : {0} {1}".format(round(total_size - transferred_size, 2), unit))
def main():
while True:
process = os.popen("ps -U root -axwwo lstart,command | grep 'zfs:' | grep -v grep")
rep_status = process.read()
process.close()
rep_status = rep_status.split(' ')
snapshot = rep_status[7]
size_dict = rep_status[9].strip(')').split('/')
transferred_size_bytes = int(size_dict[0])
transferred_size_mb = bytes_to_mb(transferred_size_bytes)
transferred_size_gb = bytes_to_gb(transferred_size_bytes)
total_size_bytes = int(size_dict[1])
total_size_mb = bytes_to_mb(total_size_bytes)
total_size_gb = bytes_to_gb(total_size_bytes)
remaining_size_bytes = total_size_bytes - transferred_size_bytes
remaining_size_mb = total_size_mb - transferred_size_mb
remaining_size_gb = total_size_gb - transferred_size_gb
refresh_time = 5
os.system('clear')
progress(snapshot, transferred_size_gb, total_size_gb, "GB")
progress_bar(transferred_size_gb, total_size_gb)
try:
before_remaining
except NameError:
print("Speed : Calculating...")
remaining_size_mb_now = remaining_size_mb
before_remaining = remaining_size_mb_now
else:
before_remaining = remaining_size_mb_now # old value
remaining_size_mb_now = remaining_size_mb # set it to new value
speed = calculate_speed(remaining_size_mb_now, before_remaining, refresh_time)
print("Speed : {} MB/s".format(round(speed, 2)))
transfer_time(remaining_size_mb, speed, get_start_datetime_from_ps(rep_status))
print("")
while refresh_time > 0:
sys.stdout.write("\rRefreshing in {}".format(refresh_time))
time.sleep(1)
refresh_time = refresh_time - 1
sys.stdout.flush()
if __name__ == '__main__':
main()
@MarcHagen
Copy link

Change rep_status = rep_status.split(' ') to rep_status = rep_status.split()
if you get a ValueError: invalid literal for int() with base 10: '(28%:'

This because my FreeNAS reported with double spaces between Nov 4 :: Thu Nov 4 21:59:41 2021 zfs: sending tank/urbackup-data@auto-1wklife-20211029_06:00 (28%: 389335000952/1362155614640) (zfs)

@Findarato
Copy link

This does not work on the most recent TrueNAS

index error for snapshot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment