Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.

Commit c6e4687

Browse files
committed
allow persisting safemode flag
1 parent a85014d commit c6e4687

File tree

3 files changed

+74
-7
lines changed

3 files changed

+74
-7
lines changed

cardano-launcher/app/Main.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,10 @@ main = silence $ do
131131
throwM $ LauncherOptionsError (show err)
132132
Right lo -> pure lo
133133

134-
let lockFile = loStateDir launcherOptions </> "daedalus_lockfile"
134+
let stateDir :: FilePath
135+
stateDir = loStateDir launcherOptions
136+
137+
let lockFile = stateDir </> "daedalus_lockfile"
135138
Trace.logNotice baseTrace $ "Locking file so that multiple applications won't run at same time"
136139
-- Check if it's locked or not. Will throw an exception if the
137140
-- application is already running.
@@ -187,6 +190,7 @@ main = silence $ do
187190
daedalusBin
188191
updaterExecutionFunction
189192
updaterData
193+
stateDir
190194

191195
-- Exit the program with exit code.
192196
exitWith exitCode

cardano-launcher/src/Cardano/Shell/Launcher.hs

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ module Cardano.Shell.Launcher
1111
-- * Functions
1212
, runLauncher
1313
, runWalletProcess
14+
, saveSafeMode
15+
, readSafeMode
1416
-- * Critical exports (testing)
1517
, DaedalusExitCode (..)
1618
, handleDaedalusExitCode
@@ -27,8 +29,11 @@ module Cardano.Shell.Launcher
2729
import Cardano.Prelude hiding (onException)
2830

2931
import Prelude (Show (..))
32+
import Data.Aeson (FromJSON, ToJSON(toJSON), genericParseJSON, genericToJSON, defaultOptions)
33+
import Data.Yaml as Y
3034
import qualified System.Process as Process
3135
import Turtle (system)
36+
import Test.QuickCheck (Arbitrary (arbitrary), elements)
3237

3338
import Cardano.Shell.Configuration (WalletArguments (..),
3439
DaedalusBin (..))
@@ -74,6 +79,29 @@ data WalletMode
7479
| WalletModeSafe
7580
deriving (Eq, Show)
7681

82+
instance Arbitrary WalletMode where
83+
arbitrary = elements [ WalletModeSafe, WalletModeNormal ]
84+
85+
instance FromJSON WalletMode where
86+
parseJSON (Bool True) = pure WalletModeSafe
87+
parseJSON (String "safe") = pure WalletModeSafe
88+
parseJSON (String "normal") = pure WalletModeNormal
89+
parseJSON _ = pure WalletModeNormal
90+
91+
instance ToJSON WalletMode where
92+
toJSON WalletModeNormal = String "normal"
93+
toJSON WalletModeSafe = String "safe"
94+
95+
data SafeModeConfig = SafeModeConfig
96+
{ smcSafeMode :: WalletMode
97+
} deriving (Generic, Show)
98+
99+
instance FromJSON SafeModeConfig where
100+
parseJSON = genericParseJSON defaultOptions
101+
102+
instance ToJSON SafeModeConfig where
103+
toJSON = genericToJSON defaultOptions
104+
77105
-- | All the important exit codes. Since we cover "other" cases as well, this is a total mapping.
78106
-- That is good.
79107
-- TODO(KS): We could extend this to try to encode some interesting properties about it.
@@ -125,6 +153,22 @@ instance Isomorphism DaedalusExitCode ExitCode where
125153
-- Functions
126154
--------------------------------------------------------------------------------
127155

156+
readSafeMode :: FilePath -> IO WalletMode
157+
readSafeMode stateDir = do
158+
let safeModeConfigFile = getSafeModeConfigPath stateDir
159+
decoded <- liftIO $ Y.decodeFileEither safeModeConfigFile
160+
case decoded of
161+
Right value -> pure $ smcSafeMode value
162+
Left _ -> pure WalletModeNormal
163+
164+
saveSafeMode :: FilePath -> WalletMode -> IO ()
165+
saveSafeMode stateDir mode = do
166+
let safeModeConfigFile = getSafeModeConfigPath stateDir
167+
Y.encodeFile safeModeConfigFile $ SafeModeConfig mode
168+
169+
getSafeModeConfigPath :: FilePath -> FilePath
170+
getSafeModeConfigPath stateDir = stateDir </> "safemode.yaml"
171+
128172
-- | Here we handle the exit codes.
129173
-- It's a simple mapping from exit code to actions that the launcher takes.
130174
--
@@ -165,25 +209,30 @@ runWalletProcess
165209
-> WalletRunner
166210
-> RunUpdateFunc
167211
-> UpdaterData
212+
-> FilePath
168213
-> IO ExitCode
169214
runWalletProcess
170215
logDep
171216
walletMode
172217
daedalusBin
173218
walletRunner
174219
runUpdateFunc
175-
updaterData = do
220+
updaterData
221+
stateDir = do
176222

177223
-- Parametrized by @WalletMode@ so we can change it on restart depending
178224
-- on the Daedalus exit code.
179225
let restart :: WalletMode -> IO ExitCode
180-
restart = \walletMode' -> runWalletProcess
226+
restart = \walletMode' -> do
227+
saveSafeMode stateDir walletMode'
228+
runWalletProcess
181229
logDep
182230
walletMode'
183231
daedalusBin
184232
walletRunner
185233
runUpdateFunc
186234
updaterData
235+
stateDir
187236

188237
-- Additional arguments we need to pass if it's a SAFE mode.
189238
let walletSafeModeArgs :: WalletArguments
@@ -269,8 +318,10 @@ runLauncher
269318
-> DaedalusBin
270319
-> RunUpdateFunc
271320
-> UpdaterData
321+
-> FilePath
272322
-> IO ExitCode
273-
runLauncher loggingDependencies walletRunner daedalusBin runUpdateFunc updaterData = do
323+
runLauncher loggingDependencies walletRunner daedalusBin runUpdateFunc updaterData stateDir = do
324+
safeMode <- readSafeMode stateDir
274325

275326
-- In the case the user wants to avoid installing the update now, we
276327
-- run the update (if there is one) when we have it downloaded.
@@ -283,11 +334,12 @@ runLauncher loggingDependencies walletRunner daedalusBin runUpdateFunc updaterDa
283334
-- You still want to run the wallet even if the update fails
284335
runWalletProcess
285336
loggingDependencies
286-
WalletModeNormal
337+
safeMode
287338
daedalusBin
288339
walletRunner
289340
runUpdateFunc
290341
updaterData
342+
stateDir
291343

292344
-- | Generation of the TLS certificates.
293345
-- This just covers the generation of the TLS certificates and nothing else.

cardano-launcher/test/LauncherSpec.hs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ import Cardano.Shell.CLI (LauncherOptionPath (..),
2121
decodeLauncherOption, setupEnvVars)
2222
import Cardano.Shell.Configuration (LauncherOptions (..),
2323
setWorkingDirectory)
24-
import Cardano.Shell.Launcher (DaedalusExitCode (..),
24+
import Cardano.Shell.Launcher (DaedalusExitCode (..), WalletMode (..),
2525
RestartRunner (..), UpdateRunner (..),
26-
handleDaedalusExitCode)
26+
handleDaedalusExitCode,
27+
readSafeMode, saveSafeMode)
2728
import Cardano.Shell.Launcher.Types (nullLogging)
2829

2930
-- | The simple launcher spec.
@@ -32,8 +33,18 @@ launcherSpec = do
3233
configurationSpec
3334
launcherSystemSpec
3435
setWorkingDirectorySpec
36+
safeModeSpec
3537
--generateTLSCertSpec
3638

39+
safeModeSpec :: Spec
40+
safeModeSpec =
41+
describe "safemode persisting system" $ modifyMaxSuccess (const 10000) $ do
42+
43+
prop "safemode roundtrips" $ \(mode :: WalletMode) -> monadicIO $ do
44+
run $ saveSafeMode "/tmp" mode
45+
readback <- run $ readSafeMode "/tmp"
46+
assert $ mode == readback
47+
3748
-- | The launcher system spec.
3849
launcherSystemSpec :: Spec
3950
launcherSystemSpec =

0 commit comments

Comments
 (0)