mirror of
https://github.com/Start9Labs/registry.git
synced 2026-03-26 10:21:51 +00:00
reworked constants into configurable settings
This commit is contained in:
6
config/compatability.json
Normal file
6
config/compatability.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"0.1.0": "1.0.0",
|
||||
"0.1.1": "1.0.0",
|
||||
"0.1.2": "1.1.0",
|
||||
"0.1.3": "1.1.0"
|
||||
}
|
||||
@@ -28,4 +28,7 @@ ip-from-header: "_env:YESOD_IP_FROM_HEADER:false"
|
||||
# NB: If you need a numeric value (e.g. 123) to parse as a String, wrap it in single quotes (e.g. "_env:YESOD_PGPASS:'123'")
|
||||
# See https://github.com/yesodweb/yesod/wiki/Configuration#parsing-numeric-values-as-strings
|
||||
|
||||
app-compatibility-path: "_env:APP_COMPATIBILITY_CONFIG:/etc/start9/registry/compatibility.json"
|
||||
app-compatibility-path: "_env:APP_COMPATIBILITY_CONFIG:/etc/start9/registry/compatibility.json"
|
||||
resources-path: "_env:RESOURCES_PATH:/var/www/html/resources"
|
||||
ssl-path: "_env:SSL_PATH:/var/ssl"
|
||||
registry-hostname: "_env:REGISTRY_HOSTNAME:registry.start9labs.com"
|
||||
@@ -165,16 +165,15 @@ startApp :: AgentCtx -> IO ()
|
||||
startApp foundation = do
|
||||
-- set up ssl certificates
|
||||
putStrLn @Text "Setting up SSL"
|
||||
setupSsl
|
||||
_ <- setupSsl <$> getAppSettings
|
||||
putStrLn @Text "SSL Setup Complete"
|
||||
|
||||
startWeb foundation
|
||||
|
||||
startWeb :: AgentCtx -> IO ()
|
||||
startWeb foundation = do
|
||||
app <- makeApplication foundation
|
||||
|
||||
putStrLn @Text $ "Launching Web Server on port " <> show (appPort $ appSettings foundation)
|
||||
let AppSettings{..} = appSettings foundation
|
||||
putStrLn @Text $ "Launching Web Server on port " <> show appPort
|
||||
action <- async $ runTLS
|
||||
(tlsSettings sslCertLocation sslKeyLocation)
|
||||
(warpSettings foundation)
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
module Constants where
|
||||
|
||||
import Data.Aeson
|
||||
import Data.Aeson.Types
|
||||
import Data.Maybe
|
||||
import Data.Version (showVersion)
|
||||
import Lib.Types.Semver
|
||||
import Paths_start9_registry (version)
|
||||
import Startlude
|
||||
|
||||
sslPath :: FilePath
|
||||
sslPath = "/var/ssl"
|
||||
|
||||
resourcesDir :: FilePath
|
||||
resourcesDir = "/var/www/html/resources" -- "./resources" --
|
||||
|
||||
registryVersion :: AppVersion
|
||||
registryVersion = fromJust . parseMaybe parseJSON . String . toS . showVersion $ version
|
||||
|
||||
getRegistryHostname :: IsString a => a
|
||||
getRegistryHostname = "registry.start9labs.com"
|
||||
@@ -23,8 +23,9 @@ import Yesod.Core
|
||||
import Foundation
|
||||
import Lib.Registry
|
||||
import Lib.Semver
|
||||
import System.FilePath ((<.>))
|
||||
import System.FilePath ((<.>), (</>))
|
||||
import System.Posix.Files (fileSize, getFileStatus)
|
||||
import Settings
|
||||
|
||||
pureLog :: Show a => a -> Handler a
|
||||
pureLog = liftA2 (*>) ($logInfo . show) pure
|
||||
@@ -38,13 +39,22 @@ instance Show FileExtension where
|
||||
show (FileExtension f (Just e)) = f <.> e
|
||||
|
||||
getAppsManifestR :: Handler TypedContent
|
||||
getAppsManifestR = respondSource typePlain $ CB.sourceFile appManifestPath .| awaitForever sendChunkBS
|
||||
getAppsManifestR = do
|
||||
AppSettings{..} <- appSettings <$> getYesod
|
||||
let appResourceDir = resourcesDir </> "apps" </> "apps.yaml"
|
||||
respondSource typePlain $ CB.sourceFile appResourceDir .| awaitForever sendChunkBS
|
||||
|
||||
getSysR :: Extension "" -> Handler TypedContent
|
||||
getSysR = getApp sysResourceDir
|
||||
getSysR e = do
|
||||
AppSettings{..} <- appSettings <$> getYesod
|
||||
let sysResourceDir = resourcesDir </> "sys"
|
||||
getApp sysResourceDir e
|
||||
|
||||
getAppR :: Extension "s9pk" -> Handler TypedContent
|
||||
getAppR = getApp appResourceDir
|
||||
getAppR e = do
|
||||
AppSettings{..} <- appSettings <$> getYesod
|
||||
let appResourceDir = resourcesDir </> "apps" </> "apps.yaml"
|
||||
getApp appResourceDir e
|
||||
|
||||
getApp :: KnownSymbol a => FilePath -> Extension a -> Handler TypedContent
|
||||
getApp rootDir ext = do
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
{-# LANGUAGE RecordWildCards #-}
|
||||
|
||||
module Handler.Icons where
|
||||
|
||||
@@ -12,10 +13,13 @@ import Yesod.Core
|
||||
|
||||
import Foundation
|
||||
import Lib.Registry
|
||||
import Settings
|
||||
import System.FilePath ((</>))
|
||||
|
||||
getIconsR :: Extension "png" -> Handler TypedContent
|
||||
getIconsR ext = do
|
||||
mPng <- liftIO $ getUnversionedFileFromDir iconsResourceDir ext
|
||||
AppSettings{..} <- appSettings <$> getYesod
|
||||
mPng <- liftIO $ getUnversionedFileFromDir (resourcesDir </> "icons") ext
|
||||
case mPng of
|
||||
Nothing -> notFound
|
||||
Just pngPath -> do
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# LANGUAGE RecordWildCards #-}
|
||||
|
||||
module Handler.Version where
|
||||
|
||||
import Startlude
|
||||
@@ -14,24 +16,30 @@ import qualified Data.Text as T
|
||||
import Network.HTTP.Types
|
||||
import Yesod.Core
|
||||
|
||||
import Constants
|
||||
import Foundation
|
||||
import Handler.Types.Status
|
||||
import Lib.Registry
|
||||
import Lib.Semver
|
||||
import Lib.Types.Semver
|
||||
import Settings
|
||||
import System.FilePath ((</>))
|
||||
|
||||
getVersionR :: Handler AppVersionRes
|
||||
getVersionR = pure . AppVersionRes registryVersion $ Nothing
|
||||
getVersionR = do
|
||||
AppSettings{..} <- appSettings <$> getYesod
|
||||
pure . AppVersionRes registryVersion $ Nothing
|
||||
|
||||
getVersionAppR :: Text -> Handler (Maybe AppVersionRes)
|
||||
getVersionAppR appId = getVersionWSpec appResourceDir appExt
|
||||
getVersionAppR appId = do
|
||||
AppSettings{..} <- appSettings <$> getYesod
|
||||
getVersionWSpec (resourcesDir </> "apps") appExt
|
||||
where
|
||||
appExt = Extension (toS appId) :: Extension "s9pk"
|
||||
|
||||
getVersionSysR :: Text -> Handler (Maybe AppVersionRes)
|
||||
getVersionSysR sysAppId = runMaybeT $ do
|
||||
avr <- MaybeT $ getVersionWSpec sysResourceDir sysExt
|
||||
AppSettings{..} <- appSettings <$> getYesod
|
||||
avr <- MaybeT $ getVersionWSpec (resourcesDir </> "sys") sysExt
|
||||
minComp <- lift $ case sysAppId of
|
||||
"agent" -> Just <$> meshCompanionCompatibility (appVersionVersion avr)
|
||||
_ -> pure Nothing
|
||||
|
||||
@@ -14,25 +14,9 @@ import System.Directory
|
||||
import System.FilePath
|
||||
import Yesod.Core
|
||||
|
||||
import Constants
|
||||
import Lib.Semver
|
||||
import Lib.Types.Semver
|
||||
|
||||
appResourceDir :: FilePath
|
||||
appResourceDir = resourcesDir </> "apps"
|
||||
|
||||
sysResourceDir :: FilePath
|
||||
sysResourceDir = resourcesDir </> "sys"
|
||||
|
||||
iconsResourceDir :: FilePath
|
||||
iconsResourceDir = resourcesDir </> "icons"
|
||||
|
||||
appManifestPath :: FilePath
|
||||
appManifestPath = appResourceDir </> appManifestFile
|
||||
|
||||
appManifestFile :: FilePath
|
||||
appManifestFile = "apps.yaml"
|
||||
|
||||
type Registry = HashMap String (HashMap AppVersion FilePath)
|
||||
|
||||
newtype RegisteredAppVersion = RegisteredAppVersion (AppVersion, FilePath) deriving (Eq, Show)
|
||||
|
||||
@@ -1,58 +1,49 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# LANGUAGE RecordWildCards #-}
|
||||
|
||||
module Lib.Ssl where
|
||||
|
||||
import Startlude
|
||||
|
||||
import Data.String.Interpolate.IsString
|
||||
import System.Directory
|
||||
import System.FilePath
|
||||
import System.Process
|
||||
|
||||
import Constants
|
||||
import Settings
|
||||
|
||||
-- openssl genrsa -out key.pem 2048
|
||||
-- openssl req -new -key key.pem -out certificate.csr
|
||||
-- openssl x509 -req -in certificate.csr -signkey key.pem -out certificate.pem
|
||||
|
||||
sslKeyLocation :: FilePath
|
||||
sslKeyLocation = sslPath </> "key.pem"
|
||||
|
||||
sslCsrLocation :: FilePath
|
||||
sslCsrLocation = sslPath </> "certificate.csr"
|
||||
|
||||
sslCertLocation :: FilePath
|
||||
sslCertLocation = sslPath </> "certificate.pem"
|
||||
|
||||
checkForSslCert :: IO Bool
|
||||
checkForSslCert =
|
||||
doesPathExist sslKeyLocation <&&> doesPathExist sslCertLocation
|
||||
|
||||
generateSslKey :: IO ExitCode
|
||||
generateSslKey = rawSystem "openssl" ["genrsa", "-out", sslKeyLocation, "2048"]
|
||||
|
||||
generateSslCert :: Text -> IO ExitCode
|
||||
generateSslCert name = rawSystem
|
||||
"openssl"
|
||||
["req", "-new", "-key", sslKeyLocation, "-out", sslCsrLocation, "-subj", [i|/CN=#{name}.local|]]
|
||||
|
||||
selfSignSslCert :: IO ExitCode
|
||||
selfSignSslCert = rawSystem
|
||||
"openssl"
|
||||
[ "x509"
|
||||
, "-req"
|
||||
, "-in"
|
||||
, sslCsrLocation
|
||||
, "-signkey"
|
||||
, sslKeyLocation
|
||||
, "-out"
|
||||
, sslCertLocation
|
||||
]
|
||||
|
||||
setupSsl :: IO ()
|
||||
setupSsl = do
|
||||
setupSsl :: AppSettings -> IO ()
|
||||
setupSsl AppSettings{..} = do
|
||||
exists <- checkForSslCert
|
||||
unless exists $ do
|
||||
void $ system $ "mkdir -p " <> sslPath
|
||||
void generateSslKey
|
||||
void $ generateSslCert getRegistryHostname
|
||||
void $ generateSslCert registryHostname
|
||||
void selfSignSslCert
|
||||
where
|
||||
checkForSslCert :: IO Bool
|
||||
checkForSslCert =
|
||||
doesPathExist sslKeyLocation <&&> doesPathExist sslCertLocation
|
||||
|
||||
generateSslKey :: IO ExitCode
|
||||
generateSslKey = rawSystem "openssl" ["genrsa", "-out", sslKeyLocation, "2048"]
|
||||
|
||||
generateSslCert :: Text -> IO ExitCode
|
||||
generateSslCert name = rawSystem
|
||||
"openssl"
|
||||
["req", "-new", "-key", sslKeyLocation, "-out", sslCsrLocation, "-subj", [i|/CN=#{name}.local|]]
|
||||
|
||||
selfSignSslCert :: IO ExitCode
|
||||
selfSignSslCert = rawSystem
|
||||
"openssl"
|
||||
[ "x509"
|
||||
, "-req"
|
||||
, "-in"
|
||||
, sslCsrLocation
|
||||
, "-signkey"
|
||||
, sslKeyLocation
|
||||
, "-out"
|
||||
, sslCertLocation
|
||||
]
|
||||
@@ -10,11 +10,17 @@ module Settings where
|
||||
import Startlude
|
||||
|
||||
import qualified Control.Exception as Exception
|
||||
import Data.Maybe
|
||||
import Data.Aeson
|
||||
import Data.Aeson.Types
|
||||
import Data.Version (showVersion)
|
||||
import Data.FileEmbed (embedFile)
|
||||
import Data.Yaml (decodeEither')
|
||||
import Network.Wai.Handler.Warp (HostPreference)
|
||||
import Yesod.Default.Config2 (applyEnvValue, configSettingsYml)
|
||||
import Paths_start9_registry (version)
|
||||
import Lib.Types.Semver
|
||||
import System.FilePath ((</>))
|
||||
|
||||
-- | Runtime settings to configure this application. These settings can be
|
||||
-- loaded from various sources: defaults, environment variables, config files,
|
||||
@@ -33,6 +39,13 @@ data AppSettings = AppSettings
|
||||
, appShouldLogAll :: Bool
|
||||
-- ^ Should all log messages be displayed?
|
||||
, appCompatibilityPath :: FilePath
|
||||
, resourcesDir :: FilePath
|
||||
, sslPath :: FilePath
|
||||
, registryHostname :: Text
|
||||
, registryVersion :: AppVersion
|
||||
, sslKeyLocation :: FilePath
|
||||
, sslCsrLocation :: FilePath
|
||||
, sslCertLocation :: FilePath
|
||||
}
|
||||
|
||||
instance FromJSON AppSettings where
|
||||
@@ -43,7 +56,15 @@ instance FromJSON AppSettings where
|
||||
appDetailedRequestLogging <- o .:? "detailed-logging" .!= True
|
||||
appShouldLogAll <- o .:? "should-log-all" .!= False
|
||||
appCompatibilityPath <- o .: "app-compatibility-path"
|
||||
|
||||
resourcesDir <- o .: "resources-path"
|
||||
sslPath <- o .: "ssl-path"
|
||||
registryHostname <- o .: "registry-hostname"
|
||||
|
||||
let sslKeyLocation = sslPath </> "key.pem"
|
||||
let sslCsrLocation = sslPath </> "certificate.csr"
|
||||
let sslCertLocation = sslPath </> "certificate.pem"
|
||||
let registryVersion = fromJust . parseMaybe parseJSON . String . toS . showVersion $ version
|
||||
|
||||
return AppSettings { .. }
|
||||
|
||||
-- | Raw bytes at compile time of @config/settings.yml@
|
||||
|
||||
Reference in New Issue
Block a user