add option to deprecate a service version based on a min os version

This commit is contained in:
Lucy Cifferello
2023-03-09 00:50:29 -07:00
parent 52bfa0a49c
commit 2f6ed1e464
8 changed files with 38 additions and 18 deletions

View File

@@ -36,7 +36,8 @@ tor-port: "_env:TOR_PORT:447"
static-bin-dir: "_env:STATIC_BIN:/usr/local/bin/" static-bin-dir: "_env:STATIC_BIN:/usr/local/bin/"
error-log-root: "_env:ERROR_LOG_ROOT:/var/log/registry/" error-log-root: "_env:ERROR_LOG_ROOT:/var/log/registry/"
marketplace-name: "_env:MARKETPLACE_NAME:CHANGE ME" marketplace-name: "_env:MARKETPLACE_NAME:CHANGE ME"
max-eos-version: "_env:MAX_VERSION:0.3.3.0" max-eos-version: "_env:MAX_VERSION:0.3.4.0"
min-eos-version: "_env:MIN_VERSION:0.3.4.0"
run-migration: "_env:RUN_MIGRATION:false" run-migration: "_env:RUN_MIGRATION:false"
database: database:

View File

@@ -31,7 +31,7 @@ import Startlude (
getCurrentTime, getCurrentTime,
maybe, maybe,
($), ($),
(.), Bool (True, False), (.), Bool (False),
) )
import System.FilePath (takeExtension) import System.FilePath (takeExtension)
import UnliftIO ( import UnliftIO (
@@ -314,6 +314,7 @@ upsertPackageVersion PackageManifest{..} = do
VersionRecord VersionRecord
now now
(Just now) (Just now)
Nothing
pkgId pkgId
packageManifestVersion packageManifestVersion
packageManifestTitle packageManifestTitle

View File

@@ -26,7 +26,7 @@ import Orphans.Emver ()
import Startlude (Down (..), Eq, Generic, Maybe (..), Ord ((<)), Show, Text, filter, fst, head, pure, sortOn, ($), (&&&), (.), (<$>), (<&>), (<=)) import Startlude (Down (..), Eq, Generic, Maybe (..), Ord ((<)), Show, Text, filter, fst, head, pure, sortOn, ($), (&&&), (.), (<$>), (<&>), (<=))
import Yesod (ToContent (toContent), ToTypedContent (..), YesodPersist (runDB), getsYesod) import Yesod (ToContent (toContent), ToTypedContent (..), YesodPersist (runDB), getsYesod)
import Yesod.Core.Types (JSONResponse (..)) import Yesod.Core.Types (JSONResponse (..))
import Settings (AppSettings(maxEosVersion)) import Settings (AppSettings(maxOsVersion))
import Lib.Types.Core (OsArch(RASPBERRYPI)) import Lib.Types.Core (OsArch(RASPBERRYPI))
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
@@ -50,7 +50,7 @@ getEosVersionR :: Handler (JSONResponse (Maybe EosRes))
getEosVersionR = do getEosVersionR = do
currentEosVersion <- fromMaybe Version { unVersion = (0,3,0,0) } <$> queryParamAs "eos-version" parseVersion currentEosVersion <- fromMaybe Version { unVersion = (0,3,0,0) } <$> queryParamAs "eos-version" parseVersion
arch <- fromMaybe RASPBERRYPI <$> getArchQuery arch <- fromMaybe RASPBERRYPI <$> getArchQuery
maxVersion <- getsYesod $ maxEosVersion . appSettings maxVersion <- getsYesod $ maxOsVersion . appSettings
allEosVersions <- runDB $ allEosVersions <- runDB $
select $ do select $ do
vers <- from $ table @OsVersion vers <- from $ table @OsVersion

View File

@@ -9,16 +9,18 @@ import Data.List (lookup)
import Data.List.NonEmpty.Extra qualified as NE import Data.List.NonEmpty.Extra qualified as NE
import Data.Tuple.Extra (second) import Data.Tuple.Extra (second)
import Database.Queries (collateVersions, getPkgDataSource) import Database.Queries (collateVersions, getPkgDataSource)
import Foundation (Handler) import Foundation (Handler, RegistryCtx (appSettings))
import Handler.Package.V1.Index (getOsVersionQuery) import Handler.Package.V1.Index (getOsVersionQuery)
import Lib.Error (S9Error (..)) import Lib.Error (S9Error (..))
import Lib.Types.Core (PkgId) import Lib.Types.Core (PkgId)
import Lib.Types.Emver (Version, satisfies) import Lib.Types.Emver (Version (..), satisfies)
import Model (VersionRecord (..)) import Model (VersionRecord (..))
import Network.HTTP.Types (status400) import Network.HTTP.Types (status400)
import Startlude (Bool (True), Down (Down), Either (..), Generic, Maybe (..), NonEmpty, Show, const, encodeUtf8, filter, flip, nonEmpty, pure, ($), (.), (<$>), (<&>)) import Startlude (Bool (True), Down (Down), Either (..), Generic, Maybe (..), NonEmpty, Show, const, encodeUtf8, filter, flip, nonEmpty, pure, ($), (.), (<$>), (<&>))
import Yesod (ToContent (..), ToTypedContent (..), YesodPersist (runDB), YesodRequest (reqGetParams), getRequest, sendResponseStatus) import Yesod (ToContent (..), ToTypedContent (..), YesodPersist (runDB), YesodRequest (reqGetParams), getRequest, sendResponseStatus)
import Handler.Util (getArchQuery) import Handler.Util (getArchQuery, filterDeprecatedVersions)
import Yesod.Core (getsYesod)
import Settings (AppSettings(minOsVersion))
newtype VersionLatestRes = VersionLatestRes (HashMap PkgId (Maybe Version)) newtype VersionLatestRes = VersionLatestRes (HashMap PkgId (Maybe Version))
@@ -38,6 +40,7 @@ getVersionLatestR = do
Nothing -> const True Nothing -> const True
Just v -> flip satisfies v Just v -> flip satisfies v
osArch <- getArchQuery osArch <- getArchQuery
minOsVersion <- getsYesod $ minOsVersion . appSettings
do do
case lookup "ids" getParameters of case lookup "ids" getParameters of
Nothing -> sendResponseStatus status400 (InvalidParamsE "get:ids" "<MISSING>") Nothing -> sendResponseStatus status400 (InvalidParamsE "get:ids" "<MISSING>")
@@ -54,6 +57,8 @@ getVersionLatestR = do
.| collateVersions .| collateVersions
-- filter out versions of apps that are incompatible with the OS predicate -- filter out versions of apps that are incompatible with the OS predicate
.| mapC (second (filter (osPredicate' . versionRecordOsVersion))) .| mapC (second (filter (osPredicate' . versionRecordOsVersion)))
-- filter out deprecated service versions after a min os version
.| mapC (second (filterDeprecatedVersions minOsVersion osPredicate'))
-- prune empty version sets -- prune empty version sets
.| concatMapC (\(pkgId, vs) -> (pkgId,) <$> nonEmpty vs) .| concatMapC (\(pkgId, vs) -> (pkgId,) <$> nonEmpty vs)
-- grab the latest matching version if it exists -- grab the latest matching version if it exists

View File

@@ -25,16 +25,16 @@ import Database.Queries (
getPkgDependencyData, getPkgDependencyData,
serviceQuerySource, serviceQuerySource,
) )
import Foundation (Handler, Route (InstructionsR, LicenseR)) import Foundation (Handler, Route (InstructionsR, LicenseR), RegistryCtx (appSettings))
import Handler.Package.Api (DependencyRes (..), PackageListRes (..), PackageRes (..)) import Handler.Package.Api (DependencyRes (..), PackageListRes (..), PackageRes (..))
import Handler.Types.Api (ApiVersion (..)) import Handler.Types.Api (ApiVersion (..))
import Handler.Util (basicRender, parseQueryParam, getArchQuery) import Handler.Util (basicRender, parseQueryParam, getArchQuery, filterDeprecatedVersions)
import Lib.PkgRepository (PkgRepo, getIcon, getManifest) import Lib.PkgRepository (PkgRepo, getIcon, getManifest)
import Lib.Types.Core (PkgId) import Lib.Types.Core (PkgId)
import Lib.Types.Emver (Version, VersionRange (..), parseRange, satisfies, (<||)) import Lib.Types.Emver (Version, VersionRange (..), parseRange, satisfies, (<||))
import Model (Category (..), Key (..), PkgDependency (..), VersionRecord (..), PkgRecord (pkgRecordHidden)) import Model (Category (..), Key (..), PkgDependency (..), VersionRecord (..), PkgRecord (pkgRecordHidden))
import Protolude.Unsafe (unsafeFromJust) import Protolude.Unsafe (unsafeFromJust)
import Settings (AppSettings) import Settings (AppSettings (minOsVersion))
import Startlude ( import Startlude (
Applicative ((*>)), Applicative ((*>)),
Bifunctor (..), Bifunctor (..),
@@ -88,8 +88,8 @@ import Yesod (
lookupGetParam, lookupGetParam,
) )
import Data.Tuple (fst) import Data.Tuple (fst)
import Data.Tuple.Extra (both)
import Database.Persist.Postgresql (entityVal) import Database.Persist.Postgresql (entityVal)
import Yesod.Core (getsYesod)
data PackageReq = PackageReq data PackageReq = PackageReq
{ packageReqId :: !PkgId { packageReqId :: !PkgId
@@ -119,6 +119,7 @@ getPackageIndexR = do
Nothing -> const True Nothing -> const True
Just v -> flip satisfies v Just v -> flip satisfies v
osArch <- getArchQuery osArch <- getArchQuery
minOsVersion <- getsYesod $ minOsVersion . appSettings
do do
pkgIds <- getPkgIdsQuery pkgIds <- getPkgIdsQuery
category <- getCategoryQuery category <- getCategoryQuery
@@ -139,6 +140,8 @@ getPackageIndexR = do
.| collateVersions .| collateVersions
-- filter out versions of apps that are incompatible with the OS predicate -- filter out versions of apps that are incompatible with the OS predicate
.| mapC (second (filter (osPredicate . versionRecordOsVersion))) .| mapC (second (filter (osPredicate . versionRecordOsVersion)))
-- filter out deprecated service versions after a min os version
.| mapC (second (filterDeprecatedVersions minOsVersion osPredicate))
-- prune empty version sets -- prune empty version sets
.| concatMapC (\(pkgId, vs) -> (pkgId,) <$> nonEmpty vs) .| concatMapC (\(pkgId, vs) -> (pkgId,) <$> nonEmpty vs)
-- grab the latest matching version if it exists -- grab the latest matching version if it exists

View File

@@ -25,13 +25,13 @@ import Lib.PkgRepository (
) )
import Lib.Types.Core (PkgId, OsArch) import Lib.Types.Core (PkgId, OsArch)
import Lib.Types.Emver ( import Lib.Types.Emver (
Version, Version (Version, unVersion),
VersionRange, VersionRange,
satisfies, parseVersion satisfies, parseVersion
) )
import Model ( import Model (
UserActivity (..), UserActivity (..),
VersionRecord (versionRecordOsVersion), VersionRecord (versionRecordOsVersion, versionRecordDeprecatedAt),
) )
import Network.HTTP.Types ( import Network.HTTP.Types (
Status, Status,
@@ -79,6 +79,7 @@ import Yesod (
) )
import Yesod.Core (addHeader, logWarn) import Yesod.Core (addHeader, logWarn)
import Lib.Error (S9Error (..)) import Lib.Error (S9Error (..))
import Data.Maybe (isJust)
orThrow :: MonadHandler m => m (Maybe a) -> m a -> m a orThrow :: MonadHandler m => m (Maybe a) -> m a -> m a
orThrow action other = orThrow action other =
@@ -175,3 +176,9 @@ fetchCompatiblePkgVersions osVersion pkg = do
getArchQuery :: Handler (Maybe OsArch) getArchQuery :: Handler (Maybe OsArch)
getArchQuery = parseQueryParam "arch" ((flip $ note . mappend "Invalid 'arch': ") =<< readMaybe) getArchQuery = parseQueryParam "arch" ((flip $ note . mappend "Invalid 'arch': ") =<< readMaybe)
filterDeprecatedVersions :: Version -> (Version -> Bool) -> [VersionRecord] -> [VersionRecord]
filterDeprecatedVersions minOsVersion osPredicate vrs = do
if (osPredicate minOsVersion)
then filter (\v -> not $ isJust $ versionRecordDeprecatedAt v) $ vrs
else vrs

View File

@@ -54,6 +54,7 @@ PkgRecord
VersionRecord sql=version VersionRecord sql=version
createdAt UTCTime createdAt UTCTime
updatedAt UTCTime Maybe updatedAt UTCTime Maybe
deprecatedAt UTCTime Maybe
pkgId PkgRecordId pkgId PkgRecordId
number Version number Version
title Text title Text

View File

@@ -75,7 +75,8 @@ data AppSettings = AppSettings
-- ^ Should all log messages be displayed? -- ^ Should all log messages be displayed?
, errorLogRoot :: !FilePath , errorLogRoot :: !FilePath
, marketplaceName :: !Text , marketplaceName :: !Text
, maxEosVersion :: !Version , maxOsVersion :: !Version
, minOsVersion :: !Version
, registryHostname :: !Text , registryHostname :: !Text
, registryVersion :: !Version , registryVersion :: !Version
, resourcesDir :: !FilePath , resourcesDir :: !FilePath
@@ -110,7 +111,8 @@ instance FromJSON AppSettings where
appShouldLogAll <- o .:? "should-log-all" .!= False appShouldLogAll <- o .:? "should-log-all" .!= False
errorLogRoot <- o .: "error-log-root" errorLogRoot <- o .: "error-log-root"
marketplaceName <- o .: "marketplace-name" marketplaceName <- o .: "marketplace-name"
maxEosVersion <- o .: "max-eos-version" maxOsVersion <- o .: "max-eos-version"
minOsVersion <- o .: "min-eos-version"
registryHostname <- o .: "registry-hostname" registryHostname <- o .: "registry-hostname"
resourcesDir <- o .: "resources-path" resourcesDir <- o .: "resources-path"
needsMigration <- o .: "run-migration" needsMigration <- o .: "run-migration"