webapp: Improve handling of remotes whose setup has stalled.

This includes recovery from the ssh-agent problem that led to many reporting
http://git-annex.branchable.com/bugs/Internal_Server_Error:_Unknown_UUID/
(Including fixing up .ssh/config to set IdentitiesOnly.)

Remotes that have no known uuid are now displayed in the webapp as
"unfinished". There's a link to check their status, and if the remote
has been set annex-ignore, a retry button can be used to unset that and
try again to set up the remote.

As this bug has shown, the process of adding a ssh remote has some failure
modes that are not really ideal. It would certianly be better if, when
setting up a ssh remote it would detect if it's failed to get the UUID,
and handle that in the remote setup process, rather than waiting until
later and handling it this way.

However, that's hard to do, particularly for local pairing, since the
PairListener runs as a background thread. The best it could do is pop up an
alert if there's a problem. This solution is not much different.

Also, this solution handles cases where the user has gotten their repo into
a mess manually and let's the assistant help with cleaning it up.

This commit was sponsored by Chia Shee Liang. Thanks!
This commit is contained in:
Joey Hess 2013-07-31 16:01:20 -04:00
parent ab62ae357a
commit d1ed337035
6 changed files with 125 additions and 36 deletions

View file

@ -13,6 +13,7 @@ import Assistant.WebApp.Common
import Assistant.DaemonStatus
import Assistant.WebApp.Notifications
import Assistant.WebApp.Utility
import Assistant.Ssh
import qualified Annex
import qualified Remote
import qualified Types.Remote as Remote
@ -22,6 +23,8 @@ import Logs.Remote
import Logs.Trust
import Logs.Group
import Config
import Git.Config
import Assistant.Sync
import Config.Cost
import qualified Git
#ifdef WITH_XMPP
@ -177,8 +180,7 @@ repoList reposelector
where
val iscloud r = Just (iscloud, (u, DisabledRepoActions $ r u))
list l = liftAnnex $ do
let l' = filter (\(u, _) -> u /= NoUUID) $
nubBy (\x y -> fst x == fst y) l
let l' = nubBy (\x y -> fst x == fst y) l
l'' <- zip
<$> Remote.prettyListUUIDs (map fst l')
<*> pure l'
@ -223,3 +225,30 @@ reorderCosts remote rs = zip rs'' (insertCostAfter costs i)
rs' = filter (\r -> Remote.uuid r /= Remote.uuid remote) rs
costs = map Remote.cost rs'
rs'' = (\(x, y) -> x ++ [remote] ++ y) $ splitAt (i + 1) rs'
{- Checks to see if any repositories with NoUUID have annex-ignore set.
- That could happen if there's a problem contacting a ssh remote
- soon after it was added. -}
getCheckUnfinishedRepositoriesR :: Handler Html
getCheckUnfinishedRepositoriesR = page "Unfinished repositories" (Just Configuration) $ do
stalled <- liftAnnex findStalled
$(widgetFile "configurators/checkunfinished")
findStalled :: Annex [Remote]
findStalled = filter isstalled <$> remoteListRefresh
where
isstalled r = Remote.uuid r == NoUUID
&& remoteAnnexIgnore (Remote.gitconfig r)
getRetryUnfinishedRepositoriesR :: Handler ()
getRetryUnfinishedRepositoriesR = do
liftAssistant $ mapM_ unstall =<< liftAnnex findStalled
redirect DashboardR
where
unstall r = do
liftIO $ fixSshKeyPair
liftAnnex $ setConfig
(remoteConfig (Remote.repo r) "ignore")
(boolConfig False)
syncRemote r
liftAnnex $ void remoteListRefresh

View file

@ -32,6 +32,8 @@
/config/repository/edit/new/cloud/#UUID EditNewCloudRepositoryR GET POST
/config/repository/sync/disable/#UUID DisableSyncR GET
/config/repository/sync/enable/#UUID EnableSyncR GET
/config/repository/unfinished/check CheckUnfinishedRepositoriesR GET
/config/repository/unfinished/retry RetryUnfinishedRepositoriesR GET
/config/repository/add/drive AddDriveR GET POST
/config/repository/add/drive/confirm/#RemovableDrive ConfirmAddDriveR GET