summaryrefslogtreecommitdiff
path: root/byteback-restore
blob: 00964f1830b03068defadaa322d485f036ba9265 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/ruby
#
# Restore a file from the most recent backup, from the remote host.
#

$LOAD_PATH.unshift("/usr/lib/byteback")
$LOAD_PATH.unshift("./lib/")

require 'trollop'


#
#  Show an error message and abort.
#
def fatal( str )
  STDERR.puts( str )
  exit(1)
end



#
#  Run a remote command.
#
def ssh(*ssh_args)
  args = ["ssh",
    "-o", "BatchMode=yes",
    "-o", "ConnectionAttempts=5",
    "-o", "ConnectTimeout=30",
    "-o", "ServerAliveInterval=60",
    "-o", "TCPKeepAlive=yes",
    "-x", "-a",
    "-i", @ssh_key,
    "-l", @destination_user,
    @destination_host
  ] +
  ssh_args.
  map { |a| a ? a : "" }

  system(*args)
end



def list_files( pattern )
  ssh("byteback-receive", "--list", pattern )
end


def restore_file( path, revision )
  puts "Restoring revision #{revision} of file #{path}"
end





#
#  Parse our command-line arguments
#
opts = Trollop::options do

  banner "byteback-restore: Restore a file\n "

  opt :file, "The file to restore",
      :type => :string

  opt :revision, "The version of the file to restore - default is 'latest'",
      :type => :string

  opt :destination, "Backup destination (i.e. user@host:/path)",
      :type => :string

  opt :ssh_key, "SSH key filename",
      :type => :string,
      :default => "/etc/byteback/key",
      :short => "k"

end



#
#  Setup default destination and key.
#
@destination = File.read("/etc/byteback/destination").chomp if
  File.exists?("/etc/byteback/destination")
@ssh_key = "/etc/byteback/key" if File.exists?("/etc/byteback/key")

#
#  Allow the command-line to override them.
#
@ssh_key = opts[:ssh_key] unless( opts[:ssh_key].nil?)
@destination = opts[:destination] unless ( opts[:destination].nil? )


#
# Check our destination is well-formed
#
if @destination =~ /^(?:(.+)@)?([^@:]+):(.+)?$/
  @destination_user, @destination_host, @destination_path = [$1, $2, $3]
else
  fatal("Destination must be a remote path, e.g. ssh@host.com:/store/backups")
end


#
#  If the user didn't specify a file then we're not restoring anything,
# and we should abort.
#
if ( opts[:file].nil? )
  fatal("You must specify a file to restore" )
end

#
#  If the user specified a file, but not a revision, then we list
# the available revisions.
#
if ( opts[:revision].nil? )
  list_files( opts[:file] )
  exit(0)
end


#
#  Restore a file
#
restore_file( opts[:file], opts[:revision] )
exit(0)