summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2012-09-08 15:07:44 -0400
committerGravatar Joey Hess <joey@kitenet.net>2012-09-08 15:07:44 -0400
commit0f0c7f8d701f813f226424d5ae2f21f40a983536 (patch)
tree607f274278fd76ff48ca774bd971f2c2256cb7e7
parentaa0227958eeb5fb1580bbd461340c6d3eb4be611 (diff)
added pair listener thread
-rw-r--r--Assistant.hs12
-rw-r--r--Assistant/Alert.hs20
-rw-r--r--Assistant/Threads/PairListener.hs50
-rw-r--r--Assistant/WebApp/Configurators/Pairing.hs26
-rw-r--r--templates/configurators/nopairing.hamlet5
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!