#endif
import qualified Utility.Debug as Debug
-import Network.Socket (HostName)
+import Network.Socket (HostName, PortNumber)
stopDaemon :: Annex ()
stopDaemon = liftIO . Utility.Daemon.stopDaemon . fromRawFilePath
-
- startbrowser is passed the url and html shim file, as well as the original
- stdout and stderr descriptors. -}
-startDaemon :: Bool -> Bool -> Maybe Duration -> Maybe String -> Maybe HostName -> Maybe (Maybe Handle -> Maybe Handle -> String -> FilePath -> IO ()) -> Annex ()
-startDaemon assistant foreground startdelay cannotrun listenhost startbrowser = do
+startDaemon :: Bool -> Bool -> Maybe Duration -> Maybe String -> Maybe HostName -> Maybe PortNumber -> Maybe (Maybe Handle -> Maybe Handle -> String -> FilePath -> IO ()) -> Annex ()
+startDaemon assistant foreground startdelay cannotrun listenhost listenport startbrowser = do
Annex.changeState $ \s -> s { Annex.daemon = True }
enableInteractiveBranchAccess
pidfile <- fromRepo gitAnnexPidFile
#endif
urlrenderer <- liftIO newUrlRenderer
#ifdef WITH_WEBAPP
- let webappthread = [ assist $ webAppThread d urlrenderer False cannotrun Nothing listenhost webappwaiter ]
+ let webappthread = [ assist $ webAppThread d urlrenderer False cannotrun Nothing listenhost listenport webappwaiter ]
#else
let webappthread = []
#endif
import qualified Annex
import Yesod
-import Network.Socket (SockAddr, HostName)
+import Network.Socket (SockAddr, HostName, PortNumber)
import Data.Text (pack, unpack)
import qualified Network.Wai.Handler.WarpTLS as TLS
import Network.Wai.Middleware.RequestLogger
-> Maybe String
-> Maybe (IO Url)
-> Maybe HostName
+ -> Maybe PortNumber
-> Maybe (Url -> FilePath -> IO ())
-> NamedThread
-webAppThread assistantdata urlrenderer noannex cannotrun postfirstrun listenhost onstartup = thread $ liftIO $ do
+webAppThread assistantdata urlrenderer noannex cannotrun postfirstrun listenhost listenport onstartup = thread $ liftIO $ do
listenhost' <- if isJust listenhost
then pure listenhost
else getAnnex $ annexListen <$> Annex.getGitConfig
+ listenport' <- if isJust listenport
+ then pure listenport
+ else getAnnex $ annexPort <$> Annex.getGitConfig
tlssettings <- getAnnex getTlsSettings
webapp <- WebApp
<$> pure assistantdata
( return $ logStdout app
, return app
)
- runWebApp tlssettings listenhost' app' $ \addr -> if noannex
+ runWebApp tlssettings listenhost' listenport' app' $ \addr -> if noannex
then withTmpFile "webapp.html" $ \tmpfile h -> do
hClose h
go tlssettings addr webapp tmpfile Nothing
annex.bwlimit-download, annex.bwlimit-upload,
and similar per-remote configs.
* Added --expected-present file matching option.
+ * webapp: Added --port option, and annex.port config.
-- Joey Hess <id@joeyh.name> Fri, 29 Dec 2023 11:52:06 -0400
start assistant o startdelay = do
if stopDaemonOption o
then stopDaemon
- else startDaemon assistant (foregroundDaemonOption o) startdelay Nothing Nothing Nothing -- does not return
+ else startDaemon assistant
+ (foregroundDaemonOption o)
+ startdelay
+ Nothing
+ Nothing
+ Nothing
+ Nothing
+ -- does not return
stop
import Control.Concurrent
import Control.Concurrent.STM
+import Network.Socket (PortNumber)
cmd :: Command
cmd = noCommit $ dontCheck repoExists $ notBareRepo $
data WebAppOptions = WebAppOptions
{ listenAddress :: Maybe String
+ , listenPort :: Maybe PortNumber
}
optParser :: CmdParamsDesc -> Parser WebAppOptions
( long "listen" <> metavar paramAddress
<> help "accept connections to this address"
))
+ <*> optional (option auto
+ ( long "port" <> metavar paramNumber
+ <> help "specify port to listen on"
+ ))
seek :: WebAppOptions -> CommandSeek
seek = commandAction . start
listenAddress' <- if isJust (listenAddress o)
then pure (listenAddress o)
else annexListen <$> Annex.getGitConfig
+ listenPort' <- if isJust (listenPort o)
+ then pure (listenPort o)
+ else annexPort <$> Annex.getGitConfig
ifM (checkpid <&&> checkshim (fromRawFilePath f))
- ( if isJust (listenAddress o)
- then giveup "The assistant is already running, so --listen cannot be used."
+ ( if isJust (listenAddress o) || isJust (listenPort o)
+ then giveup "The assistant is already running, so --listen and --port cannot be used."
else do
url <- liftIO . readFile . fromRawFilePath
=<< fromRepo gitAnnexUrlFile
then putStrLn url
else liftIO $ openBrowser browser (fromRawFilePath f) url Nothing Nothing
, do
- startDaemon True True Nothing cannotrun listenAddress' $ Just $
+ startDaemon True True Nothing cannotrun listenAddress' listenPort' $ Just $
\origout origerr url htmlshim ->
if isJust listenAddress'
then maybe noop (`hPutStrLn` url) origout
webAppThread d urlrenderer True Nothing
(callback signaler)
(listenAddress o)
+ (listenPort o)
(callback mainthread)
waitNamedThreads
where
_wait <- takeMVar v
state <- Annex.new =<< Git.CurrentRepo.get
Annex.eval state $
- startDaemon True True Nothing Nothing (listenAddress o) $ Just $
- sendurlback v
+ startDaemon True True Nothing Nothing (listenAddress o) (listenPort o)
+ (Just $ sendurlback v)
sendurlback v _origout _origerr url _htmlshim = putMVar v url
openBrowser :: Maybe FilePath -> FilePath -> String -> Maybe Handle -> Maybe Handle -> IO ()
import Utility.StatelessOpenPGP (SOPCmd(..), SOPProfile(..))
import Utility.ThreadScheduler (Seconds(..))
import Utility.Url (Scheme, mkScheme)
+import Network.Socket (PortNumber)
import Control.Concurrent.STM
import qualified Data.Set as S
, annexSecureEraseCommand :: Maybe String
, annexGenMetaData :: Bool
, annexListen :: Maybe String
+ , annexPort :: Maybe PortNumber
, annexStartupScan :: Bool
, annexHardLink :: Bool
, annexThin :: Bool
, annexSecureEraseCommand = getmaybe (annexConfig "secure-erase-command")
, annexGenMetaData = getbool (annexConfig "genmetadata") False
, annexListen = getmaybe (annexConfig "listen")
+ , annexPort = getmayberead (annexConfig "port")
, annexStartupScan = getbool (annexConfig "startupscan") True
, annexHardLink = getbool (annexConfig "hardlink") False
, annexThin = getbool (annexConfig "thin") False
- An IO action can also be run, to do something with the address,
- such as start a web browser to view the webapp.
-}
-runWebApp :: Maybe TLSSettings -> Maybe HostName -> Wai.Application -> (SockAddr -> IO ()) -> IO ()
-runWebApp tlssettings h app observer = withSocketsDo $ do
- sock <- getSocket h
+runWebApp :: Maybe TLSSettings -> Maybe HostName -> Maybe PortNumber -> Wai.Application -> (SockAddr -> IO ()) -> IO ()
+runWebApp tlssettings h p app observer = withSocketsDo $ do
+ sock <- getSocket h p
void $ forkIO $ go webAppSettings sock app
sockaddr <- getSocketName sock
observer sockaddr
halfhour = 30 * 60
{- Binds to a local socket, or if specified, to a socket on the specified
- - hostname or address. Selects any free port, unless the hostname ends with
- - ":port"
+ - hostname or address. Selects any free port, unless a port is specified.
-
- Prefers to bind to the ipv4 address rather than the ipv6 address
- of localhost, if it's available.
-}
-getSocket :: Maybe HostName -> IO Socket
-getSocket h = do
+getSocket :: Maybe HostName -> Maybe PortNumber -> IO Socket
+getSocket h p = do
#if defined (mingw32_HOST_OS)
-- The HostName is ignored by this code.
-- getAddrInfo didn't used to work on windows; current status
let addr = tupleToHostAddress (127,0,0,1)
sock <- socket AF_INET Stream defaultProtocol
preparesocket sock
- bind sock (SockAddrInet defaultPort addr)
+ bind sock (SockAddrInet (fromMaybe defaultPort p) addr)
use sock
where
#else
- addrs <- getAddrInfo (Just hints) (Just hostname) Nothing
+ addrs <- getAddrInfo (Just hints) (Just hostname) (fmap show p)
case (partition (\a -> addrFamily a == AF_INET) addrs) of
(v4addr:_, _) -> go v4addr
(_, v6addr:_) -> go v6addr
[[!meta author=yoh]]
[[!tag projects/repronim]]
+
+> [[done]] --[[Joey]]
--- /dev/null
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 4"""
+ date="2024-01-25T17:29:08Z"
+ content="""
+I found an old todo about the same thing,
+[[todo/Make_webapp_port_configurable]].
+
+The idea there was, they were using docker and wanted to open only a
+specific port selected for the webapp. So basically the same kind of thing.
+
+I think that this should be a separate --port option, to avoid needing to
+try to parse something that may be an ipv6 address or hostname, or
+whatever.
+
+I don't think that using --port should prevent the webapp from needing
+the `?auth=' part of the url, as output when using --listen.
+
+Probably it does not make sense to use --port without also using --listen,
+but if the user does use it, I don't think --port needs to output the url
+the way --listen does.
+"""]]
--- /dev/null
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 5"""
+ date="2024-01-25T18:06:15Z"
+ content="""
+Implemented --port.
+"""]]
* `--listen=address`
Useful for using the webapp on a remote computer. This makes the webapp
- listen on the specified IP address.
+ listen on the specified IP address. (Or on the address that a specified
+ hostname resolves to.)
This disables running a local web browser, and outputs the url you
can use to open the webapp.
Set annex.listen in the git config to make the webapp always
listen on an IP address.
+* `--port=number`
+
+ Use this option to specify a port for the webapp.
+ By default, the webapp picks an unused port.
+
* Also the [[git-annex-common-options]](1) can be used.
# USING HTTPS
The default is localhost. Can be either an IP address,
or a hostname that resolves to the desired address.
+* `annex.port`
+
+ Configures which port address the webapp listens on.
+ The default is to pick an unused port.
+
# CONFIGURATION VIA .gitattributes
The key-value backend used when adding a new file to the annex can be
### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
git annex seems awesome with the little bit of testing I've done. It seems like the perfect tool for what I want to accomplish. Thanks!
-> I don't think this necessarily makes sense, but there is an active bug
-> report about the same thing at
-> [[bugs/webapp_--listen_port_is_not_used__63__]]
->
-> So, closing this old todo to keep discussion in one place. [[done]]
-> --[[Joey]]
+> [[done]] via --port option --[[Joey]]