#!/usr/bin/env python

"""
NAME=${1?:No sparsebundle name given}

labels=$(hdiutil attach -nomount -noverify -noautofsck /Volumes/Time\ Machine/$NAME.sparsebundle)

disk=$(echo $labels | tr " " "\n" | tail -n2 | head -n1)

time fsck_hfs -dfry -c 1g $disk

if [ $? -ne 0 ]
then
    time fsck_hfs -p $disk
    time fsck_hfs -dfry -c 1g $disk
fi

hdiutil detach $disk
#!/bin/bash

TM_BUNDLE="$1"

cd "/Volumes/Time Machine"
chflags nouchg "$TM_BUNDLE" "$TM_BUNDLE/token"
hdiutil attach -nomount -noverify -noautofsck "$TM_BUNDLE"
fsck_hfs -drfy -c 1024 /dev/disk2s2
if [ $? -ne 0 ]
then
    fsck_hfs -p /dev/disk2s2
    fsck_hfs -drfy -c 1024 /dev/disk2s2
fi
success = $?
hdiutil detach /dev/disk2s2

if [ $success -eq 0 ]
then
    sed -ibck 's/<key>RecoveryBackupDeclinedDate</key>//g' "$TM_BUNDLE/com.apple.TimeMachine.MachineID.plist"
fi
"""
@@ -830,12 +830,2028 @@
 list%22%0Afi%0A%22%22%22
+%0A%0Afrom os import path%0Aimport argparse%0Aimport yaml%0Afrom paramiko.client import SSHClient%0A%0Aclass TimeMachineFixer(object):%0A  initial_snapshot = None%0A  current_snapshot = None%0A  ssh_connection = None%0A  configuration = None%0A%0A  def __init__(self, configuration):%0A    self.configuration = configuration%0A    self.ssh_connection = SSHClient()%0A    self.ssh_connection.load_system_host_keys()%0A    self.ssh_connection.connect(self.configuration%5B'freenas_host'%5D)%0A%0A  def create_initial_snapshot(self):%0A    %22%22%22%0A    Create snapshot before changing any data%0A    %22%22%22%0A    self.initial_snapshot = self.configuration%5B'dataset'%5D + '@time-machine-fixer'%0A    stdin, stdout, stderr = self.ssh_connection.exec_command('sudo zfs snapshot -r ' + self.initial_snapshot)%0A    for line in stdout.readlines():%0A      print line.strip()%0A    for line in stderr.readlines():%0A      print line.strip()%0A    stdin, stdout, stderr = self.ssh_connection.exec_command('ls -1 /mnt/' + self.configuration%5B'dataset'%5D + '/.zfs/snapshot/')%0A    for line in stdout.readlines():%0A      print line.strip()%0A%0A  def destroy_initial_snapshot(self):%0A    %22%22%22%0A    Go back to the state before start of fixing process%0A    %22%22%22%0A    stdin, stdout, stderr = self.ssh_connection.exec_command('sudo zfs destroy -r ' + self.initial_snapshot)%0A    for line in stdout.readlines():%0A      print line.strip()%0A    stdin, stdout, stderr = self.ssh_connection.exec_command('ls -1 /mnt/' + self.configuration%5B'dataset'%5D + '/.zfs/snapshot/')%0A    for line in stdout.readlines():%0A      print line.strip()%0A%0A%0Adef load_configuration(config_file):%0A  config_stream = open(config_file, %22r%22)%0A  configuration = yaml.load(config_stream)%0A  return configuration%0A%0Adef main():%0A  parser = argparse.ArgumentParser()%0A  parser.add_argument(%22sparsebundle%22)%0A  args = parser.parse_args()%0A  configuration = load_configuration(path.expanduser(%22~%22) + %22/.time-machine-fixer.yml%22)%0A  tmf = TimeMachineFixer(configuration)%0A  tmf.create_initial_snapshot()%0A  tmf.destroy_initial_snapshot()%0A%0Aif __name__ == '__main__':%0A  main()%0A

Create snapshot before changing any data and revert to that state afterwards