From e467478f40c3951dc86abbbe2a31c66f3eadb01b Mon Sep 17 00:00:00 2001 From: Matthias Fischmann Date: Mon, 30 Jan 2023 14:16:25 +0100 Subject: [PATCH 1/9] Make stern assert backend api version [WIP] --- tools/stern/exec/Main.hs | 3 ++- tools/stern/src/Stern/Intra.hs | 13 ++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tools/stern/exec/Main.hs b/tools/stern/exec/Main.hs index 58540a30ade..6096177cc88 100644 --- a/tools/stern/exec/Main.hs +++ b/tools/stern/exec/Main.hs @@ -22,10 +22,11 @@ where import Imports import Stern.API +import Stern.Intra (assertBackendApiVersion) import Util.Options main :: IO () -main = getOptions desc Nothing defaultPath >>= start +main = assertBackendApiVersion >> getOptions desc Nothing defaultPath >>= start where desc = "Stern - Backoffice Service" defaultPath = "/etc/wire/stern/conf/stern.yaml" diff --git a/tools/stern/src/Stern/Intra.hs b/tools/stern/src/Stern/Intra.hs index cc40ca1b902..7a5154322dc 100644 --- a/tools/stern/src/Stern/Intra.hs +++ b/tools/stern/src/Stern/Intra.hs @@ -22,7 +22,8 @@ -- with this program. If not, see . module Stern.Intra - ( putUser, + ( assertBackendApiVersion, + putUser, putUserStatus, getContacts, getUserConnections, @@ -114,6 +115,16 @@ import Wire.API.User.Search ------------------------------------------------------------------------------- +backendApiVersion :: Version +backendApiVersion = V2 + +-- | Make sure the backend supports `backendApiVersion`. Crash horribly if it doesn't. (This +-- should be caught by the integration tests.) +assertBackendApiVersion :: IO () +assertBackendApiVersion = undefined backendApiVersion + +------------------------------------------------------------------------------- + putUser :: UserId -> UserUpdate -> Handler () putUser uid upd = do info $ userMsg uid . msg "Changing user state" From 436035877d78c916fad867ff4452c6cd9fd4da2f Mon Sep 17 00:00:00 2001 From: Matthias Fischmann Date: Mon, 30 Jan 2023 14:22:46 +0100 Subject: [PATCH 2/9] ... --- libs/wire-api/src/Wire/API/Routes/Version.hs | 5 +++++ tools/stern/src/Stern/Intra.hs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libs/wire-api/src/Wire/API/Routes/Version.hs b/libs/wire-api/src/Wire/API/Routes/Version.hs index 68d46bf8ee5..be29c11e1f4 100644 --- a/libs/wire-api/src/Wire/API/Routes/Version.hs +++ b/libs/wire-api/src/Wire/API/Routes/Version.hs @@ -43,6 +43,8 @@ import Control.Lens ((?~)) import Data.Aeson (FromJSON, ToJSON (..)) import qualified Data.Aeson as Aeson import Data.Bifunctor +import Data.ByteString.Builder (string7) +import Data.ByteString.Conversion (ToByteString (builder)) import qualified Data.ByteString.Lazy as LBS import Data.Domain import Data.Schema @@ -61,6 +63,9 @@ data Version = V0 | V1 | V2 | V3 deriving stock (Eq, Ord, Bounded, Enum, Show) deriving (FromJSON, ToJSON) via (Schema Version) +instance ToByteString Version where + builder = string7 . show + instance ToSchema Version where schema = enum @Integer "Version" . mconcat $ diff --git a/tools/stern/src/Stern/Intra.hs b/tools/stern/src/Stern/Intra.hs index 7a5154322dc..402ae75db3d 100644 --- a/tools/stern/src/Stern/Intra.hs +++ b/tools/stern/src/Stern/Intra.hs @@ -757,7 +757,7 @@ getUserConversations uid = do b ( method GET . header "Z-User" (toByteString' uid) - . path "/v2/conversations" + . paths [toByteString' backendApiVersion, "conversations"] . queryItem "size" (toByteString' batchSize) . maybe id (queryItem "start" . toByteString') start . expect2xx From 0c12e2f78401440645770931c789978fab45ea47 Mon Sep 17 00:00:00 2001 From: Matthias Fischmann Date: Mon, 30 Jan 2023 14:56:35 +0100 Subject: [PATCH 3/9] ... --- tools/stern/exec/Main.hs | 3 +-- tools/stern/src/Stern/API.hs | 1 + tools/stern/src/Stern/Intra.hs | 14 ++++++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/tools/stern/exec/Main.hs b/tools/stern/exec/Main.hs index 6096177cc88..58540a30ade 100644 --- a/tools/stern/exec/Main.hs +++ b/tools/stern/exec/Main.hs @@ -22,11 +22,10 @@ where import Imports import Stern.API -import Stern.Intra (assertBackendApiVersion) import Util.Options main :: IO () -main = assertBackendApiVersion >> getOptions desc Nothing defaultPath >>= start +main = getOptions desc Nothing defaultPath >>= start where desc = "Stern - Backoffice Service" defaultPath = "/etc/wire/stern/conf/stern.yaml" diff --git a/tools/stern/src/Stern/API.hs b/tools/stern/src/Stern/API.hs index aba2ca29189..65acf6fc795 100644 --- a/tools/stern/src/Stern/API.hs +++ b/tools/stern/src/Stern/API.hs @@ -74,6 +74,7 @@ default (ByteString) start :: Opts -> IO () start o = do e <- newEnv o + runAppT e $ Intra.assertBackendApiVersion s <- Server.newSettings (server e) Server.runSettingsWithShutdown s (servantApp e) Nothing where diff --git a/tools/stern/src/Stern/Intra.hs b/tools/stern/src/Stern/Intra.hs index 402ae75db3d..c8398c2ba17 100644 --- a/tools/stern/src/Stern/Intra.hs +++ b/tools/stern/src/Stern/Intra.hs @@ -118,10 +118,16 @@ import Wire.API.User.Search backendApiVersion :: Version backendApiVersion = V2 --- | Make sure the backend supports `backendApiVersion`. Crash horribly if it doesn't. (This --- should be caught by the integration tests.) -assertBackendApiVersion :: IO () -assertBackendApiVersion = undefined backendApiVersion +-- | Make sure the backend supports `backendApiVersion`. Crash if it doesn't. (Call this so +-- problems are caught by the integration tests.) +assertBackendApiVersion :: App () +assertBackendApiVersion = do + b <- view brig + vinfo :: VersionInfo <- + responseJsonError + =<< rpc' "brig" b (method GET . path "/api-version" . contentJson . expect2xx) + unless (maximum (vinfoSupported vinfo) == backendApiVersion) $ do + throwError . ErrorCall $ "newest supported backend api version must be " <> show backendApiVersion ------------------------------------------------------------------------------- From ff175bdeeaa01d41cee8171a9661b69e42812991 Mon Sep 17 00:00:00 2001 From: Matthias Fischmann Date: Mon, 30 Jan 2023 15:43:58 +0100 Subject: [PATCH 4/9] ... --- tools/stern/src/Stern/Intra.hs | 6 ++++-- tools/stern/stern.cabal | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/stern/src/Stern/Intra.hs b/tools/stern/src/Stern/Intra.hs index c8398c2ba17..17eaaf344b2 100644 --- a/tools/stern/src/Stern/Intra.hs +++ b/tools/stern/src/Stern/Intra.hs @@ -66,6 +66,7 @@ import Bilge hiding (head, options, requestId) import Bilge.RPC import Brig.Types.Intra import Control.Error +import Control.Exception (ErrorCall (ErrorCall)) import Control.Lens (view, (^.)) import Control.Monad.Reader import Data.Aeson hiding (Error) @@ -95,6 +96,7 @@ import Stern.Types import System.Logger.Class hiding (Error, name, (.=)) import qualified System.Logger.Class as Log import UnliftIO.Exception hiding (Handler) +import UnliftIO.Retry (constantDelay, limitRetries, recoverAll) import Wire.API.Connection import Wire.API.Conversation import Wire.API.Internal.Notification @@ -121,13 +123,13 @@ backendApiVersion = V2 -- | Make sure the backend supports `backendApiVersion`. Crash if it doesn't. (Call this so -- problems are caught by the integration tests.) assertBackendApiVersion :: App () -assertBackendApiVersion = do +assertBackendApiVersion = recoverAll (constantDelay 1000000 <> limitRetries 5) $ \_retryStatus -> do b <- view brig vinfo :: VersionInfo <- responseJsonError =<< rpc' "brig" b (method GET . path "/api-version" . contentJson . expect2xx) unless (maximum (vinfoSupported vinfo) == backendApiVersion) $ do - throwError . ErrorCall $ "newest supported backend api version must be " <> show backendApiVersion + throwIO . ErrorCall $ "newest supported backend api version must be " <> show backendApiVersion ------------------------------------------------------------------------------- diff --git a/tools/stern/stern.cabal b/tools/stern/stern.cabal index 2fc74138b43..d0924fbf3bb 100644 --- a/tools/stern/stern.cabal +++ b/tools/stern/stern.cabal @@ -91,6 +91,7 @@ library , lens >=4.4 , metrics-wai >=0.3 , mtl >=2.1 + , retry , schema-profunctor , servant , servant-server From a70f7d33bfa423a4e9c228f038fd9c27410cdf97 Mon Sep 17 00:00:00 2001 From: Matthias Fischmann Date: Mon, 30 Jan 2023 15:48:52 +0100 Subject: [PATCH 5/9] ... --- tools/stern/src/Stern/Intra.hs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/stern/src/Stern/Intra.hs b/tools/stern/src/Stern/Intra.hs index 17eaaf344b2..0b159195581 100644 --- a/tools/stern/src/Stern/Intra.hs +++ b/tools/stern/src/Stern/Intra.hs @@ -62,7 +62,8 @@ module Stern.Intra ) where -import Bilge hiding (head, options, requestId) +import Bilge hiding (head, options, path, paths, requestId) +import qualified Bilge import Bilge.RPC import Brig.Types.Intra import Control.Error @@ -127,10 +128,16 @@ assertBackendApiVersion = recoverAll (constantDelay 1000000 <> limitRetries 5) $ b <- view brig vinfo :: VersionInfo <- responseJsonError - =<< rpc' "brig" b (method GET . path "/api-version" . contentJson . expect2xx) + =<< rpc' "brig" b (method GET . Bilge.path "/api-version" . contentJson . expect2xx) unless (maximum (vinfoSupported vinfo) == backendApiVersion) $ do throwIO . ErrorCall $ "newest supported backend api version must be " <> show backendApiVersion +path :: ByteString -> Request -> Request +path = Bilge.path . ((toByteString' backendApiVersion <> "/") <>) + +paths :: [ByteString] -> Request -> Request +paths = Bilge.paths . (toByteString' backendApiVersion :) + ------------------------------------------------------------------------------- putUser :: UserId -> UserUpdate -> Handler () @@ -765,7 +772,7 @@ getUserConversations uid = do b ( method GET . header "Z-User" (toByteString' uid) - . paths [toByteString' backendApiVersion, "conversations"] + . path "conversations" . queryItem "size" (toByteString' batchSize) . maybe id (queryItem "start" . toByteString') start . expect2xx From 56373d86923b6fbcbb266c8a18baafca4c5152c5 Mon Sep 17 00:00:00 2001 From: Matthias Fischmann Date: Mon, 30 Jan 2023 15:52:03 +0100 Subject: [PATCH 6/9] ... --- libs/wire-api/src/Wire/API/Routes/Version.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/wire-api/src/Wire/API/Routes/Version.hs b/libs/wire-api/src/Wire/API/Routes/Version.hs index be29c11e1f4..886c6cb9699 100644 --- a/libs/wire-api/src/Wire/API/Routes/Version.hs +++ b/libs/wire-api/src/Wire/API/Routes/Version.hs @@ -63,9 +63,6 @@ data Version = V0 | V1 | V2 | V3 deriving stock (Eq, Ord, Bounded, Enum, Show) deriving (FromJSON, ToJSON) via (Schema Version) -instance ToByteString Version where - builder = string7 . show - instance ToSchema Version where schema = enum @Integer "Version" . mconcat $ @@ -88,6 +85,9 @@ instance ToHttpApiData Version where toHeader = LBS.toStrict . Aeson.encode toUrlPiece = Text.decodeUtf8 . toHeader +instance ToByteString Version where + builder = toEncodedUrlPiece + supportedVersions :: [Version] supportedVersions = [minBound .. maxBound] From 046624b8e8b235abe6d82d52dadf70b1c3b85189 Mon Sep 17 00:00:00 2001 From: Matthias Fischmann Date: Mon, 30 Jan 2023 15:53:59 +0100 Subject: [PATCH 7/9] ... --- libs/wire-api/src/Wire/API/Routes/Version.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/wire-api/src/Wire/API/Routes/Version.hs b/libs/wire-api/src/Wire/API/Routes/Version.hs index 886c6cb9699..fa6b4303948 100644 --- a/libs/wire-api/src/Wire/API/Routes/Version.hs +++ b/libs/wire-api/src/Wire/API/Routes/Version.hs @@ -43,7 +43,6 @@ import Control.Lens ((?~)) import Data.Aeson (FromJSON, ToJSON (..)) import qualified Data.Aeson as Aeson import Data.Bifunctor -import Data.ByteString.Builder (string7) import Data.ByteString.Conversion (ToByteString (builder)) import qualified Data.ByteString.Lazy as LBS import Data.Domain From 7f4f3e81c4a157e20eaf6ab10c240687964668a6 Mon Sep 17 00:00:00 2001 From: Matthias Fischmann Date: Mon, 30 Jan 2023 15:54:05 +0100 Subject: [PATCH 8/9] changelog --- changelog.d/5-internal/pr-3036 | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5-internal/pr-3036 diff --git a/changelog.d/5-internal/pr-3036 b/changelog.d/5-internal/pr-3036 new file mode 100644 index 00000000000..6d052dfcf0b --- /dev/null +++ b/changelog.d/5-internal/pr-3036 @@ -0,0 +1 @@ +Make stern fail on startup if supported backend api version needs bumping \ No newline at end of file From f7b0bdd357eb8487fe81541ffeaca4824f393c49 Mon Sep 17 00:00:00 2001 From: Leif Battermann Date: Mon, 30 Jan 2023 16:18:13 +0100 Subject: [PATCH 9/9] Update tools/stern/src/Stern/Intra.hs Co-authored-by: fisx --- tools/stern/src/Stern/Intra.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/stern/src/Stern/Intra.hs b/tools/stern/src/Stern/Intra.hs index 0b159195581..c27ef368297 100644 --- a/tools/stern/src/Stern/Intra.hs +++ b/tools/stern/src/Stern/Intra.hs @@ -121,8 +121,8 @@ import Wire.API.User.Search backendApiVersion :: Version backendApiVersion = V2 --- | Make sure the backend supports `backendApiVersion`. Crash if it doesn't. (Call this so --- problems are caught by the integration tests.) +-- | Make sure the backend supports `backendApiVersion`. Crash if it doesn't. (This is called +-- in `Stern.API` so problems make `./services/integration.sh` crash.) assertBackendApiVersion :: App () assertBackendApiVersion = recoverAll (constantDelay 1000000 <> limitRetries 5) $ \_retryStatus -> do b <- view brig