1 #!/usr/bin/python |
1 #!/usr/bin/python |
2 |
2 |
3 """ |
3 """ |
4 SSH authorized_keys command="..." wrapper for rsync. |
4 SSH authorized_keys command="..." wrapper for rsync. |
|
5 |
|
6 Testing goes something like: |
|
7 sudo sh -c "PYTHONPATH=. rsync -e './scripts/pvlbackup-rsync-wrapper --debug -C --' -ax testing:lvm:asdf:test test/tmp" |
5 """ |
8 """ |
6 |
9 |
7 from pvl.backup.rsync import RSyncCommandFormatError |
10 from pvl.backup.rsync import RSyncCommandFormatError |
8 from pvl.backup.invoke import InvokeError |
11 from pvl.backup.invoke import InvokeError |
9 from pvl.backup import rsync |
12 from pvl.backup import rsync |
10 |
13 |
11 import optparse |
14 import optparse |
|
15 import shlex |
12 import os |
16 import os |
13 import logging |
17 import logging |
14 |
18 |
15 log = logging.getLogger() |
19 log = logging.getLogger() |
16 |
20 |
39 parser.add_option_group(general) |
45 parser.add_option_group(general) |
40 |
46 |
41 # |
47 # |
42 parser.add_option('-c', '--command', metavar='CMD', default=os.environ.get('SSH_ORIGINAL_COMMAND'), |
48 parser.add_option('-c', '--command', metavar='CMD', default=os.environ.get('SSH_ORIGINAL_COMMAND'), |
43 help="rsync command to execute") |
49 help="rsync command to execute") |
|
50 |
|
51 parser.add_option('-C', '--given-command', action='store_true', default=False, |
|
52 help="use given command in `rsync -e %prog` format") |
44 |
53 |
45 parser.add_option('-R', '--readonly', action='store_true', default=False, |
54 parser.add_option('-R', '--readonly', action='store_true', default=False, |
46 help="restrict to read/source mode") |
55 help="restrict to read/source mode") |
47 |
56 |
48 parser.add_option('-P', '--restrict-path', metavar='PATH', default=False, |
57 parser.add_option('-P', '--restrict-path', metavar='PATH', default=False, |
110 global options |
119 global options |
111 |
120 |
112 # global options + args |
121 # global options + args |
113 options, args = parse_options(argv) |
122 options, args = parse_options(argv) |
114 |
123 |
|
124 # command required |
|
125 if options.given_command : |
|
126 # from args (as given by `rsync -e pvlbackup-rsync-wrapper`) -> 'pvlbackup-rsync-wrapper <host> (<command> ...)' |
|
127 host = args.pop(0) |
|
128 command_parts = args |
|
129 |
|
130 log.debug("using command from args: %r", command_parts) |
|
131 |
115 # args |
132 # args |
116 if args : |
133 elif args : |
117 log.error("No arguments are handled") |
134 log.error("No arguments are handled") |
118 return 2 |
135 return 2 |
119 |
136 |
120 # command required |
137 elif options.command: |
121 if not options.command: |
138 # as given |
|
139 command_parts = shlex.split(options.command) |
|
140 |
|
141 else : |
122 log.error("SSH_ORIGINAL_COMMAND not given") |
142 log.error("SSH_ORIGINAL_COMMAND not given") |
123 return 2 |
143 return 2 |
124 |
144 |
|
145 |
|
146 # run |
125 try : |
147 try : |
126 # handle it |
148 return rsync_wrapper(command_parts) |
127 return rsync_wrapper(options.command) |
|
128 |
149 |
129 except Exception, e: |
150 except Exception, e: |
130 log.error("Internal error:", exc_info=e) |
151 log.error("Internal error:", exc_info=e) |
131 return 3 |
152 return 3 |
132 |
153 |