blog for the weekend
This commit is contained in:
parent
b885c0c6c8
commit
d04e023ded
1 changed files with 99 additions and 0 deletions
|
@ -0,0 +1,99 @@
|
|||
Spent yesterday and today making the WebApp handle adding removable drives.
|
||||
|
||||
While it needs more testing, I think that it's now possible to use the WebApp
|
||||
for a complete sneakernet usage scenario.
|
||||
|
||||
* Start up the webapp, let it make a local repo.
|
||||
* Add some files, by clicking to open the file manager, and dragging them in.
|
||||
* Plug in a drive, and tell the webapp to add it.
|
||||
* Wait while files sync..
|
||||
* Take the drive to another computer, and repeat the process there.
|
||||
|
||||
No command-line needed, and files will automatically be synced between
|
||||
two or more computers using the drive.
|
||||
|
||||
Sneakernet is only one usage scenario for the git-annex assistant, but I'm
|
||||
really happy to have one scenario 100% working!
|
||||
|
||||
Indeed, since the assistant and webapp can now actually do something
|
||||
useful, I'll probably be merging them into `master` soon.
|
||||
|
||||
Details follow..
|
||||
|
||||
---
|
||||
|
||||
So, yesterday's part of this was building the configuration page to add
|
||||
a removable drive. That needs to be as simple as possible, and it currently
|
||||
consists of a list of things git-annex thinks might be mount points of
|
||||
removable drives, along with how much free space they have. Pick a drive,
|
||||
click the pretty button, and away it goes..
|
||||
|
||||
(I decided to make the page so simple it doesn't even ask where you want
|
||||
to put the directory on the removable drive. It always puts it in
|
||||
a "annex" directory. I might add an expert screen later, but experts can
|
||||
always set this up themselves at the command line too.)
|
||||
|
||||
I also fought with Yesod and Bootstrap rather a lot to make the form look good.
|
||||
Didn't entirely succeed, and had to file a bug on Yesod about its handling of
|
||||
check boxes. (Bootstrap also has a bug, IMHO; its drop down lists are not
|
||||
always sized wide enough for their contents.)
|
||||
|
||||
Ideally this configuration page would listen for mount events, and refresh
|
||||
its list. I may add that eventually; I didn't have a handy channel it
|
||||
could use to do that, so defferred it. Another idea is to have the mount
|
||||
event listener detect removable drives that don't have an annex on them yet,
|
||||
and pop up an alert with a link to this configuration page.
|
||||
|
||||
----
|
||||
|
||||
Making the form led to a somewhat interesting problem: How to tell if a mounted
|
||||
filesystem is a removable drive, or some random thing like `/proc` or
|
||||
a fuse filesystem. My answer, besides checking that the user can
|
||||
write to it, was various heuristics, which seem to work ok, at least here..
|
||||
|
||||
[[!format haskell """
|
||||
sane Mntent { mnt_dir = dir, mnt_fsname = dev }
|
||||
{- We want real disks like /dev/foo, not
|
||||
- dummy mount points like proc or tmpfs or
|
||||
- gvfs-fuse-daemon. -}
|
||||
| not ('/' `elem` dev) = False
|
||||
{- Just in case: These mount points are surely not
|
||||
- removable disks. -}
|
||||
| dir == "/" = False
|
||||
| dir == "/tmp" = False
|
||||
| dir == "/run/shm" = False
|
||||
| dir == "/run/lock" = False
|
||||
"""]]
|
||||
|
||||
----
|
||||
|
||||
Today I did all the gritty coding to make it create a git repository on the
|
||||
removable drive, and tell the Annex monad about it, and ensure it gets synced.
|
||||
|
||||
As part of that, it detects when the removable drive's filesystem doesn't
|
||||
support symlinks, and makes a bare repository in that case. Another expert
|
||||
level config option that's left out for now is to always make a bare
|
||||
repository, or even to make a directory special remote rather than a git
|
||||
repository at all. (But directory special remotes cannot support the
|
||||
sneakernet use case by themselves...)
|
||||
|
||||
----
|
||||
|
||||
Another somewhat interesting problem was what to call the git remotes
|
||||
that it sets up on the removable drive and the local repository.
|
||||
Again this could have an expert-level configuration, but the defaults
|
||||
I chose are to use the hostname as the remote name on the removable drive,
|
||||
and to use the basename of the mount point of the removable drive as the
|
||||
remote name in the local annex.
|
||||
|
||||
----
|
||||
|
||||
Originally, I had thought of this as cloning the repository to the drive.
|
||||
But, partly due to luck, I started out just doing a `git init` to make
|
||||
the repository (I had a function lying around to do that..).
|
||||
|
||||
And as I worked on it some more, I realized this is not as simple as a
|
||||
clone. It's a bi-directional sync/merge, and indeed the removable drive may
|
||||
have all the data already in it, and the local repository have just been
|
||||
created. Handling all the edge cases of that (like, the local repository
|
||||
may not have a "master" branch yet..) was fun!
|
Loading…
Add table
Reference in a new issue