mirror of
https://github.com/Start9Labs/registry.git
synced 2026-03-31 04:03:40 +00:00
proper manifest parsing
This commit is contained in:
@@ -179,7 +179,7 @@ getServiceR = do
|
|||||||
Nothing -> sendResponseStatus status404 ("id param should exist" :: Text)
|
Nothing -> sendResponseStatus status404 ("id param should exist" :: Text)
|
||||||
Just appId' -> do
|
Just appId' -> do
|
||||||
case lookup "version" getParameters of
|
case lookup "version" getParameters of
|
||||||
-- default to latest - need to determine best available based on OS version?
|
-- default to latest - @TODO need to determine best available based on OS version?
|
||||||
Nothing -> runDB $ fetchLatestApp appId' >>= errOnNothing status404 "service not found"
|
Nothing -> runDB $ fetchLatestApp appId' >>= errOnNothing status404 "service not found"
|
||||||
Just v -> do
|
Just v -> do
|
||||||
case readMaybe v of
|
case readMaybe v of
|
||||||
@@ -191,7 +191,6 @@ getServiceR = do
|
|||||||
let appId = sAppAppId $ entityVal service
|
let appId = sAppAppId $ entityVal service
|
||||||
let appDir = (<> "/") . (</> show (sVersionNumber $ entityVal version)) . (</> toS appId) $ appsDir
|
let appDir = (<> "/") . (</> show (sVersionNumber $ entityVal version)) . (</> toS appId) $ appsDir
|
||||||
let appExt = Extension (toS appId) :: Extension "s9pk"
|
let appExt = Extension (toS appId) :: Extension "s9pk"
|
||||||
$logInfo $ "*******************" <> show appDir
|
|
||||||
manifest' <- handleS9ErrT $ getManifest appMgrDir appDir appExt
|
manifest' <- handleS9ErrT $ getManifest appMgrDir appDir appExt
|
||||||
manifest <- case eitherDecode $ BS.fromStrict manifest' of
|
manifest <- case eitherDecode $ BS.fromStrict manifest' of
|
||||||
Left e -> do
|
Left e -> do
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
{-# LANGUAGE DeriveAnyClass #-}
|
{-# LANGUAGE DeriveAnyClass #-}
|
||||||
{-# LANGUAGE DeriveGeneric #-}
|
{-# LANGUAGE DeriveGeneric #-}
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
|
||||||
module Lib.Types.AppIndex where
|
module Lib.Types.AppIndex where
|
||||||
|
|
||||||
import Startlude hiding ( Any )
|
import Startlude hiding ( Any )
|
||||||
@@ -18,6 +20,10 @@ import System.Directory
|
|||||||
import Lib.Registry
|
import Lib.Registry
|
||||||
import Model
|
import Model
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
import Data.String.Interpolate.IsString
|
||||||
|
import qualified Data.ByteString.Lazy as BS
|
||||||
|
import Data.Tuple.Extra
|
||||||
|
import qualified Data.Attoparsec.Text as Atto
|
||||||
|
|
||||||
type AppIdentifier = Text
|
type AppIdentifier = Text
|
||||||
|
|
||||||
@@ -124,27 +130,26 @@ addFileTimestamp appDir ext service v = do
|
|||||||
|
|
||||||
data ServiceDependencyInfo = ServiceDependencyInfo
|
data ServiceDependencyInfo = ServiceDependencyInfo
|
||||||
{ serviceDependencyInfoOptional :: Maybe Text
|
{ serviceDependencyInfoOptional :: Maybe Text
|
||||||
, serviceDependencyInfoRecommended :: Bool
|
, serviceDependencyInfoVersion :: VersionRange
|
||||||
, serviceDependencyInfoVersion :: Version
|
|
||||||
, serviceDependencyInfoDescription :: Maybe Text
|
, serviceDependencyInfoDescription :: Maybe Text
|
||||||
|
, serviceDependencyInfoCritical :: Bool
|
||||||
} deriving (Show)
|
} deriving (Show)
|
||||||
instance FromJSON ServiceDependencyInfo where
|
instance FromJSON ServiceDependencyInfo where
|
||||||
parseJSON = withObject "service dependency info" $ \o -> do
|
parseJSON = withObject "service dependency info" $ \o -> do
|
||||||
serviceDependencyInfoOptional <- o .:? "optional"
|
serviceDependencyInfoOptional <- o .:? "optional"
|
||||||
serviceDependencyInfoRecommended <- o .: "recommended"
|
|
||||||
serviceDependencyInfoVersion <- o .: "version"
|
serviceDependencyInfoVersion <- o .: "version"
|
||||||
serviceDependencyInfoDescription <- o .:? "description"
|
serviceDependencyInfoDescription <- o .:? "description"
|
||||||
|
serviceDependencyInfoCritical <- o .: "critical"
|
||||||
pure ServiceDependencyInfo { .. }
|
pure ServiceDependencyInfo { .. }
|
||||||
|
|
||||||
instance ToJSON ServiceDependencyInfo where
|
instance ToJSON ServiceDependencyInfo where
|
||||||
toJSON ServiceDependencyInfo {..} = object
|
toJSON ServiceDependencyInfo {..} = object
|
||||||
[ "description" .= serviceDependencyInfoDescription
|
[ "description" .= serviceDependencyInfoDescription
|
||||||
, "version" .= serviceDependencyInfoVersion
|
, "version" .= serviceDependencyInfoVersion
|
||||||
, "recommended" .= serviceDependencyInfoRecommended
|
|
||||||
, "optional" .= serviceDependencyInfoOptional
|
, "optional" .= serviceDependencyInfoOptional
|
||||||
|
, "critical" .= serviceDependencyInfoCritical
|
||||||
]
|
]
|
||||||
data ServiceAlert = INSTALL | UNINSTALL | RESTORE | START | STOP
|
data ServiceAlert = INSTALL | UNINSTALL | RESTORE | START | STOP
|
||||||
deriving (Show, Eq, Generic, Hashable)
|
deriving (Show, Eq, Generic, Hashable, Read)
|
||||||
instance FromJSONKey ServiceAlert
|
instance FromJSONKey ServiceAlert
|
||||||
instance ToJSONKey ServiceAlert
|
instance ToJSONKey ServiceAlert
|
||||||
instance ToJSON ServiceAlert where
|
instance ToJSON ServiceAlert where
|
||||||
@@ -157,7 +162,7 @@ instance FromJSON ServiceAlert where
|
|||||||
"start" -> pure START
|
"start" -> pure START
|
||||||
"stop" -> pure STOP
|
"stop" -> pure STOP
|
||||||
_ -> fail "unknown service alert type"
|
_ -> fail "unknown service alert type"
|
||||||
data ServiceManifest = ServiceManifest
|
data ServiceManifest = ServiceManifest
|
||||||
{ serviceManifestId :: AppIdentifier
|
{ serviceManifestId :: AppIdentifier
|
||||||
, serviceManifestTitle :: Text
|
, serviceManifestTitle :: Text
|
||||||
, serviceManifestVersion :: Version
|
, serviceManifestVersion :: Version
|
||||||
@@ -175,7 +180,14 @@ instance FromJSON ServiceManifest where
|
|||||||
serviceManifestDescriptionLong <- o .: "description" >>= (.: "long")
|
serviceManifestDescriptionLong <- o .: "description" >>= (.: "long")
|
||||||
serviceManifestDescriptionShort <- o .: "description" >>= (.: "short")
|
serviceManifestDescriptionShort <- o .: "description" >>= (.: "short")
|
||||||
serviceManifestReleaseNotes <- o .: "release-notes"
|
serviceManifestReleaseNotes <- o .: "release-notes"
|
||||||
serviceManifestAlerts <- o .: "alerts"
|
alerts <- o .: "alerts"
|
||||||
|
a <- for (HM.toList alerts) $ \(key, value) -> do
|
||||||
|
alertType <- case readMaybe $ T.toUpper key of
|
||||||
|
Nothing -> fail "could not parse alert key as ServiceAlert"
|
||||||
|
Just t -> pure t
|
||||||
|
alertDesc <- parseJSON value
|
||||||
|
pure (alertType, alertDesc)
|
||||||
|
let serviceManifestAlerts = HM.fromList a
|
||||||
serviceManifestDependencies <- o .: "dependencies"
|
serviceManifestDependencies <- o .: "dependencies"
|
||||||
pure ServiceManifest { .. }
|
pure ServiceManifest { .. }
|
||||||
instance ToJSON ServiceManifest where
|
instance ToJSON ServiceManifest where
|
||||||
@@ -187,4 +199,146 @@ instance ToJSON ServiceManifest where
|
|||||||
, "release-notes" .= serviceManifestReleaseNotes
|
, "release-notes" .= serviceManifestReleaseNotes
|
||||||
, "alerts" .= serviceManifestAlerts
|
, "alerts" .= serviceManifestAlerts
|
||||||
, "dependencies" .= serviceManifestDependencies
|
, "dependencies" .= serviceManifestDependencies
|
||||||
]
|
]
|
||||||
|
|
||||||
|
-- >>> eitherDecode testManifest :: Either String ServiceManifest
|
||||||
|
-- Right (ServiceManifest {serviceManifestId = "embassy-pages", serviceManifestTitle = "Embassy Pages", serviceManifestVersion = 0.1.3, serviceManifestDescriptionLong = "Embassy Pages is a simple web server that uses directories inside File Browser to serve Tor websites.", serviceManifestDescriptionShort = "Create Tor websites, hosted on your Embassy.", serviceManifestReleaseNotes = "Upgrade to EmbassyOS v0.3.0", serviceManifestAlerts = fromList [(INSTALL,Nothing),(UNINSTALL,Nothing),(STOP,Nothing),(RESTORE,Nothing),(START,Nothing)], serviceManifestDependencies = fromList [("filebrowser",ServiceDependencyInfo {serviceDependencyInfoOptional = Nothing, serviceDependencyInfoVersion = >=2.14.1.1 <3.0.0, serviceDependencyInfoDescription = Just "Used to upload files to serve.", serviceDependencyInfoCritical = False})]})
|
||||||
|
testManifest :: BS.ByteString
|
||||||
|
testManifest = [i|{
|
||||||
|
"id": "embassy-pages",
|
||||||
|
"title": "Embassy Pages",
|
||||||
|
"version": "0.1.3",
|
||||||
|
"description": {
|
||||||
|
"short": "Create Tor websites, hosted on your Embassy.",
|
||||||
|
"long": "Embassy Pages is a simple web server that uses directories inside File Browser to serve Tor websites."
|
||||||
|
},
|
||||||
|
"assets": {
|
||||||
|
"license": "LICENSE",
|
||||||
|
"icon": "icon.png",
|
||||||
|
"docker-images": "image.tar",
|
||||||
|
"instructions": "instructions.md"
|
||||||
|
},
|
||||||
|
"build": [
|
||||||
|
"make"
|
||||||
|
],
|
||||||
|
"release-notes": "Upgrade to EmbassyOS v0.3.0",
|
||||||
|
"license": "nginx",
|
||||||
|
"wrapper-repo": "https://github.com/Start9Labs/embassy-pages-wrapper",
|
||||||
|
"upstream-repo": "http://hg.nginx.org/nginx/",
|
||||||
|
"support-site": null,
|
||||||
|
"marketing-site": null,
|
||||||
|
"alerts": {
|
||||||
|
"install": null,
|
||||||
|
"uninstall": null,
|
||||||
|
"restore": null,
|
||||||
|
"start": null,
|
||||||
|
"stop": null
|
||||||
|
},
|
||||||
|
"main": {
|
||||||
|
"type": "docker",
|
||||||
|
"image": "main",
|
||||||
|
"system": false,
|
||||||
|
"entrypoint": "/usr/local/bin/docker_entrypoint.sh",
|
||||||
|
"args": [],
|
||||||
|
"mounts": {
|
||||||
|
"filebrowser": "/mnt/filebrowser"
|
||||||
|
},
|
||||||
|
"io-format": "yaml",
|
||||||
|
"inject": false,
|
||||||
|
"shm-size-mb": null
|
||||||
|
},
|
||||||
|
"health-checks": {},
|
||||||
|
"config": {
|
||||||
|
"get": {
|
||||||
|
"type": "docker",
|
||||||
|
"image": "compat",
|
||||||
|
"system": true,
|
||||||
|
"entrypoint": "config",
|
||||||
|
"args": [
|
||||||
|
"get",
|
||||||
|
"/root"
|
||||||
|
],
|
||||||
|
"mounts": {},
|
||||||
|
"io-format": "yaml",
|
||||||
|
"inject": false,
|
||||||
|
"shm-size-mb": null
|
||||||
|
},
|
||||||
|
"set": {
|
||||||
|
"type": "docker",
|
||||||
|
"image": "compat",
|
||||||
|
"system": true,
|
||||||
|
"entrypoint": "config",
|
||||||
|
"args": [
|
||||||
|
"set",
|
||||||
|
"/root"
|
||||||
|
],
|
||||||
|
"mounts": {},
|
||||||
|
"io-format": "yaml",
|
||||||
|
"inject": false,
|
||||||
|
"shm-size-mb": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"volumes": {
|
||||||
|
"filebrowser": {
|
||||||
|
"type": "pointer",
|
||||||
|
"package-id": "filebrowser",
|
||||||
|
"volume-id": "main",
|
||||||
|
"path": "/",
|
||||||
|
"readonly": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"min-os-version": "0.3.0",
|
||||||
|
"interfaces": {
|
||||||
|
"main": {
|
||||||
|
"tor-config": {
|
||||||
|
"port-mapping": {
|
||||||
|
"80": "80"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lan-config": null,
|
||||||
|
"ui": true,
|
||||||
|
"protocols": [
|
||||||
|
"tcp",
|
||||||
|
"http"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backup": {
|
||||||
|
"create": {
|
||||||
|
"type": "docker",
|
||||||
|
"image": "compat",
|
||||||
|
"system": true,
|
||||||
|
"entrypoint": "true",
|
||||||
|
"args": [],
|
||||||
|
"mounts": {},
|
||||||
|
"io-format": null,
|
||||||
|
"inject": false,
|
||||||
|
"shm-size-mb": null
|
||||||
|
},
|
||||||
|
"restore": {
|
||||||
|
"type": "docker",
|
||||||
|
"image": "compat",
|
||||||
|
"system": true,
|
||||||
|
"entrypoint": "true",
|
||||||
|
"args": [],
|
||||||
|
"mounts": {},
|
||||||
|
"io-format": null,
|
||||||
|
"inject": false,
|
||||||
|
"shm-size-mb": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"migrations": {
|
||||||
|
"from": {},
|
||||||
|
"to": {}
|
||||||
|
},
|
||||||
|
"actions": {},
|
||||||
|
"dependencies": {
|
||||||
|
"filebrowser": {
|
||||||
|
"version": ">=2.14.1.1 <3.0.0",
|
||||||
|
"optional": null,
|
||||||
|
"description": "Used to upload files to serve.",
|
||||||
|
"critical": false,
|
||||||
|
"config": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}|]
|
||||||
|
|||||||
Reference in New Issue
Block a user