diff options
author | Joey Hess <joey@kitenet.net> | 2012-09-08 15:07:44 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2012-09-08 15:07:44 -0400 |
commit | 0f0c7f8d701f813f226424d5ae2f21f40a983536 (patch) | |
tree | 607f274278fd76ff48ca774bd971f2c2256cb7e7 | |
parent | aa0227958eeb5fb1580bbd461340c6d3eb4be611 (diff) |
added pair listener thread
-rw-r--r-- | Assistant.hs | 12 | ||||
-rw-r--r-- | Assistant/Alert.hs | 20 | ||||
-rw-r--r-- | Assistant/Threads/PairListener.hs | 50 | ||||
-rw-r--r-- | Assistant/WebApp/Configurators/Pairing.hs | 26 | ||||
-rw-r--r-- | templates/configurators/nopairing.hamlet | 5 |
5 files changed, 110 insertions, 3 deletions
diff --git a/Assistant.hs b/Assistant.hs index 7f38fdf25..0141f5f56 100644 --- a/Assistant.hs +++ b/Assistant.hs @@ -63,8 +63,10 @@ - Thread 16: TransferScanner - Does potentially expensive checks to find data that needs to be - transferred from or to remotes, and queues Transfers. - - Uses the ScanRemotes map. - - Thread 17: WebApp + - Uses the ScanRemotes map.a + - Thread 17: PairListener + - Listens for incoming pairing traffic, and takes action. + - Thread 18: WebApp - Spawns more threads as necessary to handle clients. - Displays the DaemonStatus. - @@ -124,6 +126,9 @@ import Assistant.Threads.TransferScanner import Assistant.Threads.TransferPoller #ifdef WITH_WEBAPP import Assistant.Threads.WebApp +#ifdef WITH_PAIRING +import Assistant.Threads.PairListener +#endif #else #warning Building without the webapp. You probably need to install Yesod.. #endif @@ -169,6 +174,9 @@ startAssistant assistant daemonize webappwaiter = do [ watch $ commitThread st changechan commitchan transferqueue dstatus #ifdef WITH_WEBAPP , assist $ webAppThread (Just st) dstatus scanremotes transferqueue transferslots Nothing webappwaiter +#ifdef WITH_PAIRING + , assist $ pairListenerThread st dstatus +#endif #endif , assist $ pushThread st dstatus commitchan pushmap , assist $ pushRetryThread st dstatus pushmap diff --git a/Assistant/Alert.hs b/Assistant/Alert.hs index 296f992bd..cb2366f44 100644 --- a/Assistant/Alert.hs +++ b/Assistant/Alert.hs @@ -27,7 +27,11 @@ data AlertPriority = Filler | Low | Medium | High | Pinned {- An alert can have an name, which is used to combine it with other similar - alerts. -} -data AlertName = FileAlert TenseChunk | SanityCheckFixAlert | WarningAlert String +data AlertName + = FileAlert TenseChunk + | SanityCheckFixAlert + | WarningAlert String + | PairRequestAlert String deriving (Eq) {- The first alert is the new alert, the second is an old alert. @@ -259,6 +263,20 @@ sanityCheckFixAlert msg = Alert alerthead = "The daily sanity check found and fixed a problem:" alertfoot = "If these problems persist, consider filing a bug report." +pairRequestAlert :: String -> String -> Alert +pairRequestAlert repo msg = Alert + { alertClass = Message + , alertHeader = Just $ tenseWords ["Pair request"] + , alertMessageRender = tenseWords + , alertData = [UnTensed $ T.pack msg] + , alertBlockDisplay = True + , alertPriority = High + , alertClosable = True + , alertIcon = Just "info-sign" + , alertName = Just $ PairRequestAlert repo + , alertCombiner = Just $ dataCombiner $ const id + } + fileAlert :: TenseChunk -> FilePath -> Alert fileAlert msg file = (activityAlert Nothing [f]) { alertName = Just $ FileAlert msg diff --git a/Assistant/Threads/PairListener.hs b/Assistant/Threads/PairListener.hs new file mode 100644 index 000000000..f76f0ed4e --- /dev/null +++ b/Assistant/Threads/PairListener.hs @@ -0,0 +1,50 @@ +{- git-annex assistant thread to listen for incoming pairing traffic + - + - Copyright 2012 Joey Hess <joey@kitenet.net> + - + - Licensed under the GNU GPL version 3 or higher. + -} + +module Assistant.Threads.PairListener where + +import Assistant.Common +import Assistant.Pairing +import Assistant.ThreadedMonad +import Assistant.DaemonStatus +import Assistant.Alert +import Utility.Verifiable + +import Network.Multicast +import Network.Socket + +thisThread :: ThreadName +thisThread = "PairListener" + +pairListenerThread :: ThreadState -> DaemonStatusHandle -> NamedThread +pairListenerThread st dstatus = thread $ withSocketsDo $ do + sock <- multicastReceiver (multicastAddress $ IPv4Addr undefined) pairingPort + forever $ do + msg <- getmsg sock [] + dispatch $ readish msg + where + thread = NamedThread thisThread + + getmsg sock c = do + (msg, n, _) <- recvFrom sock chunksz + if n < chunksz + then return $ c ++ msg + else getmsg sock $ c ++ msg + where + chunksz = 1024 + + dispatch Nothing = noop + dispatch (Just (PairReqM (PairReq r))) = void $ do + let pairdata = verifiableVal r + let repo = remoteUserName pairdata ++ "@" ++ + fromMaybe (showAddr $ remoteAddress pairdata) + (remoteHostName pairdata) + let msg = repo ++ " is sending a pair request." + {- Pair request alerts from the same host combine, + - so repeated requests do not add additional alerts. -} + addAlert dstatus $ pairRequestAlert repo msg + dispatch (Just (PairAckM _)) = noop -- TODO diff --git a/Assistant/WebApp/Configurators/Pairing.hs b/Assistant/WebApp/Configurators/Pairing.hs index e314b9526..d79752426 100644 --- a/Assistant/WebApp/Configurators/Pairing.hs +++ b/Assistant/WebApp/Configurators/Pairing.hs @@ -24,11 +24,14 @@ -} {-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings, RankNTypes #-} +{-# LANGUAGE CPP #-} module Assistant.WebApp.Configurators.Pairing where import Assistant.Common +#ifdef WITH_PAIRING import Assistant.Pairing +#endif import Assistant.DaemonStatus import Utility.Verifiable import Assistant.WebApp @@ -46,6 +49,7 @@ import Data.Char import System.Posix.User getStartPairR :: Handler RepHtml +#ifdef WITH_PAIRING getStartPairR = promptSecret Nothing $ \rawsecret secret -> do hostname <- liftIO $ getHostname username <- liftIO $ getUserName @@ -57,17 +61,29 @@ getStartPairR = promptSecret Nothing $ \rawsecret secret -> do liftIO $ modifyDaemonStatus_ dstatus $ \s -> s { pairingInProgress = pip : pairingInProgress s } lift $ redirect $ InprogressPairR rawsecret +#else +getStartPairR = noPairing +#endif getInprogressPairR :: Text -> Handler RepHtml +#ifdef WITH_PAIRING getInprogressPairR secret = bootstrap (Just Config) $ do sideBarDisplay setTitle "Pairing" $(widgetFile "configurators/inprogresspairing") +#else +getInprogressPairR _ = noPairing +#endif getFinishPairR :: PairReq -> Handler RepHtml +#ifdef WITH_PAIRING getFinishPairR req = promptSecret (Just req) $ \_ secret -> do error "TODO" +#else +getFinishPairR _ = noPairing +#endif +#ifdef WITH_PAIRING data InputSecret = InputSecret { secretText :: Maybe Text } promptSecret :: Maybe PairReq -> (Text -> Secret -> Widget) -> Handler RepHtml @@ -128,3 +144,13 @@ sampleQuote = T.unwords getUserName :: IO String getUserName = userName <$> (getUserEntryForID =<< getEffectiveUserID) + +#else + +noPairing :: Handler RepHtml +noPairing = bootstrap (Just Config) $ do + sideBarDisplay + setTitle "Pairing" + $(widgetFile "configurators/nopairing") + +#endif diff --git a/templates/configurators/nopairing.hamlet b/templates/configurators/nopairing.hamlet new file mode 100644 index 000000000..c946aacc4 --- /dev/null +++ b/templates/configurators/nopairing.hamlet @@ -0,0 +1,5 @@ +<div .span9 .hero-unit> + <h2> + Pairing not supported + <p> + This build of git-annex does not support pairing. Sorry! |