git prints the error *before* the usage message, but the more I play with it, the more I'm annoyed by that behaviour. The usage message can be pretty long, and the error gots lost way above the usage message. The most important thing *is* the error, so let's print it last. Signed-off-by: Avery Pennarun <email@example.com>
This avoids an extra process showing up in the 'ps' listing if we're not going to be using bup-newliner anyhow. Signed-off-by: Avery Pennarun <firstname.lastname@example.org>
Well, that was easy, since vfs.py already existed and is doing most of the hard work. Only 103 lines including all the log message handling and whatnot. Only one catch: the restoring code is definitely not optimized. Among other things (like the probably-excessive-for-our-restoring-needs layering in vfs.py), we're still calling into 'git cat-file --stdin' to retrieve our objects. This involves lots and lots of context switches, plus it can't use midx files for its lookups. The result is that restoring takes much more CPU time and memory than it really should. But oh well, we have to start somewhere. Signed-off-by: Avery Pennarun <email@example.com>
Previously we just assumed it was 70 chars, which was safe enough, but not as elegant as actually reading the real value and adjusting the word wrap of the usage string accordingly. Signed-off-by: Avery Pennarun <firstname.lastname@example.org>
There's a new global bup option, --debug (-D) that increments BUP_DEBUG. If BUP_DEBUG >=1, debug1() prints; if >= 2, debug2() prints. We change a bunch of formerly-always-printing log() messages to debug1 or debug2, so now a typical bup session should be a lot less noisy. This affects midx in particular, which was *way* too noisy now that 'bup save' and 'bup server' were running it automatically every now and then. Signed-off-by: Avery Pennarun <email@example.com>
Now that 'bup midx -a' is smarter, we should run it automatically after creating a new index file. This should remove the need for running it by hand. Thus, we also remove 'bup midx' from the lists of commonly-used subcommands. (While we're here, let's take out 'split' and 'join' too; you should be using 'index' and 'save' most of the time.) Signed-off-by: Avery Pennarun <firstname.lastname@example.org>
'rbackup' was a dumb name but I couldn't think of anything better at the time. This works nicely in a grammatical sort of way: bup on myserver save -n myserver-backup /etc Now that we've settled on a name, also add some documentation for the command. Signed-off-by: Avery Pennarun <email@example.com>
Gabriel Filion pointed out that bup's version number (which we added to the man pages automatically) was not detected when you used a bup tarball generated from 'git archive' (or more likely, you let GitHub call 'git archive' for you). That makes sense, since our version detection was based on having a .git directory around, which the tarball doesn't. Instead, let's create a .gitattributes file and have it auto-substitute some version information during 'git archive'. Of course, if we actually *do* have a .git directory, continue to use that. While we're here, add a new 'bup version' command and alias "bup --version" and "bup -V" to call it, since those options are pretty standard.
We use the columnate() function from main.py for this, now moved into helpers.py.
Also change main.py to search around in appropriate places for the installed library files. By default, if your bup is in /usr/bin/bup, it'll look in /usr/lib/bup. (It drops two words off the end of the filename and adds /lib/bup to the end.) This also makes the Debian packager at http://git.debian.org/collab-maint/bup actually produce a usable package.
subprocess.Popen() is a little weird about when it closes the file descriptors you give it. In this case, we have to dup() it because if stderr=2 (the default) and stdout=2 (because fix_stderr), it'll close fd 2. But if we dup it first, it *won't* close the dup, because stdout!=stderr. So we have to dup it, but then we have to close it ourselves. This was apparently harmless (it just resulted in an extra fd#3 getting passed around to subprocesses as a clone of fd#2) but it was still wrong.
If the child doesn't die after the first SIGINT and the user presses ctrl-c one more time, the main bup process would die instead of forwarding it on to the child. That's no good; we actually have to loop forwarding signals until the child is really good and dead. And if the child refuses to die, well, he's the one with the bug, not main.py. So main.py should stay alive too in the name of not losing track of things.
Ever since we introduced bup newliner, signal handling has been a little screwy. The problem is that ctrl-c is passed to *all* processes in the process group, not just the parent, so everybody would start terminating at the same time, with very messy results. Two results were particularly annoying: git.PackWriter()'s destructor wouldn't always get called (so half-finished packs would be lost instead of kept so we don't need to backup the same stuff next time) and bup-newliner would exit, so the stdout/stderr of a process that *did* try to clean up would be lost, usually resulting in EPIPE, which killed the proces while attempting to clean up. The fix is simple: when starting a long-running subprocess, give it its own session by calling os.setsid(). That way ctrl-c is only sent to the toplevel 'bup' process, who can forward it as it should. Next, fix bup's signal forwarding to actually forward the same signal as it received, instead of always using SIGTERM.
It's probably just a bug in python 2.4.2, which is the version on my old MacOS machine. But it seems that if you use subprocess.Popen with stdout=1 and/or stderr=2, it ends up closing the file descriptors instead of passing them along. Since those are the defaults anyway, just use None instead.
Otherwise, if we fail to run the subprocess, the finally section doesn't work quite right.
… dir. Remote server mode tries to add the directory of argv (the currently-running program) to the PATH on the remote server, just in case bup isn't installed in the PATH there, so that it can then run 'bup server'. However, now that bup-save is in a different place than bup, argv is the wrong place to look. Instead, have the bup executable export an environment variable containing its location, and client.py can use that instead of argv. Slightly gross, but it works.
Also add a 'help' command to ftp, and fix up some minor help messages.
We were printing output using a series of dots, which interacted badly with bup newliner (and for good reason). Change it to actually display the number of megabytes done so far. Also, don't print random binary data to a tty unless -f is given. It's just more polite that way.
When you just type 'bup' or 'bup help', we print a list of available commands. Now we improve this list by: 1) Listing the common commands (with one-line descriptions) before listing the automatically-generated list. 2) Printing the automatically-generated list in columns, so it takes up less vertical space. This whole concept was stolen from how git does it. I think it should be a bit more user friendly for beginners this way.
The bup-* programs shouldn't need to be installed into /usr/bin; we should search for them in /usr/lib somewhere. I could have left the names as cmd/cmd-*.py, but the cmd-* was annoying me because of tab completion. Now I can type cmd/ran<tab> to get random-cmd.py.
...and update other programs so that they import them correctly from their new location. This is necessary so that the bup library files can eventually be installed somewhere other than wherever the 'bup' executable ends up. Plus it's clearer and safer to say 'from bup import options' instead of just 'import options', in case someone else writes an 'options' module. I wish I could have named the directory just 'bup', but I can't; there's already a program with that name. Also, in the name of sanity, rename memtest.py to 'bup memtest' so that it can get the new paths automatically.