mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
Fix/integration/0.2.11 (#265)
* backports tor security fix to 0.2.10, adds functionality to allow for ssh key management during an update (#263) * actually upgrade to 0.3.5.14-1 * update lan services on backup restore * reload nginx, update welcome message, move reset lan to handler * moves lan refresh after backup restore to asynchronous part of restore * fix certificate generation * match guards Co-authored-by: Keagan McClelland <keagan.mcclelland@gmail.com>
This commit is contained in:
@@ -186,6 +186,8 @@ cutoffDuringUpdate m = do
|
||||
path <- asks $ pathInfo . reqWaiRequest . handlerRequest
|
||||
case path of
|
||||
[v] | v == "v" <> (show . major $ agentVersion) -> m
|
||||
[auth] | auth == "auth" -> m
|
||||
(_:ssh:_) | ssh == "sshKeys" -> m
|
||||
_ -> handleS9ErrT $ throwE UpdateInProgressE
|
||||
Nothing -> m
|
||||
|
||||
|
||||
@@ -109,7 +109,11 @@ type AllEffects m
|
||||
( Labelled
|
||||
"databaseConnection"
|
||||
(ReaderT ConnectionPool)
|
||||
(ReaderT AgentCtx (ErrorC S9Error (LiftC m)))
|
||||
( Labelled
|
||||
"lanThread"
|
||||
(ReaderT (MVar ThreadId))
|
||||
(ReaderT AgentCtx (ErrorC S9Error (LiftC m)))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -122,6 +126,8 @@ intoHandler m = do
|
||||
runM
|
||||
. handleS9ErrC
|
||||
. flip runReaderT ctx
|
||||
. flip runReaderT (appLanThread ctx)
|
||||
. runLabelled @"lanThread"
|
||||
. flip runReaderT (appConnPool ctx)
|
||||
. runLabelled @"databaseConnection"
|
||||
. flip runReaderT fsbase
|
||||
@@ -376,6 +382,7 @@ postUninstallAppLogic :: ( HasFilesystemBase sig m
|
||||
, MonadIO m
|
||||
, HasLabelled "databaseConnection" (Reader ConnectionPool) sig m
|
||||
, HasLabelled "iconTagCache" (Reader (TVar (HM.HashMap AppId (Digest MD5)))) sig m
|
||||
, HasLabelled "lanThread" (Reader (MVar ThreadId)) sig m
|
||||
)
|
||||
=> AppId
|
||||
-> AppMgr2.DryRun
|
||||
@@ -413,6 +420,7 @@ postInstallNewAppR appId = do
|
||||
|
||||
postInstallNewAppLogic :: forall sig m a
|
||||
. ( Has (Reader AgentCtx) sig m
|
||||
, HasLabelled "lanThread" (Reader (MVar ThreadId)) sig m
|
||||
, HasLabelled "databaseConnection" (Reader ConnectionPool) sig m
|
||||
, HasLabelled "iconTagCache" (Reader (TVar (HM.HashMap AppId (Digest MD5)))) sig m
|
||||
, Has (Error S9Error) sig m
|
||||
|
||||
@@ -7,11 +7,11 @@ import Startlude hiding ( Reader
|
||||
, runReader
|
||||
)
|
||||
|
||||
import Control.Effect.Labelled hiding ( Handler )
|
||||
import Control.Effect.Reader.Labelled
|
||||
import Control.Carrier.Error.Church
|
||||
import Control.Carrier.Lift
|
||||
import Control.Carrier.Reader ( runReader )
|
||||
import Control.Effect.Labelled hiding ( Handler )
|
||||
import Control.Effect.Reader.Labelled
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.UUID.V4
|
||||
@@ -20,8 +20,13 @@ import Yesod.Auth
|
||||
import Yesod.Core
|
||||
import Yesod.Core.Types
|
||||
|
||||
import Control.Concurrent.STM
|
||||
import Exinst
|
||||
import Foundation
|
||||
import Handler.Network
|
||||
import Handler.Util
|
||||
import qualified Lib.Algebra.Domain.AppMgr as AppMgr2
|
||||
import Lib.Background
|
||||
import Lib.Error
|
||||
import qualified Lib.External.AppMgr as AppMgr
|
||||
import qualified Lib.Notifications as Notifications
|
||||
@@ -29,10 +34,6 @@ import Lib.Password
|
||||
import Lib.Types.Core
|
||||
import Lib.Types.Emver
|
||||
import Model
|
||||
import qualified Lib.Algebra.Domain.AppMgr as AppMgr2
|
||||
import Lib.Background
|
||||
import Control.Concurrent.STM
|
||||
import Exinst
|
||||
|
||||
|
||||
data CreateBackupReq = CreateBackupReq
|
||||
@@ -58,8 +59,9 @@ instance FromJSON RestoreBackupReq where
|
||||
pure RestoreBackupReq { .. }
|
||||
|
||||
data EjectDiskReq = EjectDiskReq
|
||||
{ ejectDiskLogicalName :: Text
|
||||
} deriving (Eq, Show)
|
||||
{ ejectDiskLogicalName :: Text
|
||||
}
|
||||
deriving (Eq, Show)
|
||||
instance FromJSON EjectDiskReq where
|
||||
parseJSON = withObject "Eject Disk Req" $ \o -> do
|
||||
ejectDiskLogicalName <- o .: "logicalName"
|
||||
@@ -100,6 +102,8 @@ postRestoreBackupR appId = disableEndpointOnFailedUpdate $ do
|
||||
& runReader appConnPool
|
||||
& runLabelled @"backgroundJobCache"
|
||||
& runReader appBackgroundJobs
|
||||
& runLabelled @"lanThread"
|
||||
& runReader appLanThread
|
||||
& handleS9ErrC
|
||||
& runM
|
||||
|
||||
@@ -173,6 +177,7 @@ stopBackupLogic appId = do
|
||||
|
||||
restoreBackupLogic :: ( HasLabelled "backgroundJobCache" (Reader (TVar JobCache)) sig m
|
||||
, HasLabelled "databaseConnection" (Reader ConnectionPool) sig m
|
||||
, HasLabelled "lanThread" (Reader (MVar ThreadId)) sig m
|
||||
, Has (Error S9Error) sig m
|
||||
, Has AppMgr2.AppMgr sig m
|
||||
, MonadIO m
|
||||
@@ -181,10 +186,11 @@ restoreBackupLogic :: ( HasLabelled "backgroundJobCache" (Reader (TVar JobCache)
|
||||
-> RestoreBackupReq
|
||||
-> m ()
|
||||
restoreBackupLogic appId RestoreBackupReq {..} = do
|
||||
jobCache <- ask @"backgroundJobCache"
|
||||
db <- ask @"databaseConnection"
|
||||
version <- fmap AppMgr2.infoResVersion $ AppMgr2.info [AppMgr2.flags| |] appId `orThrowM` NotFoundE "appId"
|
||||
(show appId)
|
||||
lanThread <- ask @"lanThread"
|
||||
jobCache <- ask @"backgroundJobCache"
|
||||
db <- ask @"databaseConnection"
|
||||
version <- fmap AppMgr2.infoResVersion $ AppMgr2.info [AppMgr2.flags| |] appId `orThrowM` NotFoundE "appId"
|
||||
(show appId)
|
||||
res <- liftIO . atomically $ do
|
||||
(JobCache jobs) <- readTVar jobCache
|
||||
case HM.lookup appId jobs of
|
||||
@@ -206,10 +212,13 @@ restoreBackupLogic appId RestoreBackupReq {..} = do
|
||||
let notif = case appmgrRes of
|
||||
Left e -> Notifications.RestoreFailed e
|
||||
Right _ -> Notifications.RestoreSucceeded
|
||||
resetRes <- runExceptT @S9Error $ runReader lanThread . runLabelled @"lanThread" $ postResetLanLogic
|
||||
case resetRes of
|
||||
Left _ -> pure () -- temporarily forbidden is the only possible thing here so ignore it
|
||||
Right () -> pure ()
|
||||
flip runSqlPool db $ void $ Notifications.emit appId version notif
|
||||
liftIO . atomically $ modifyTVar jobCache (insertJob appId Restore tid)
|
||||
|
||||
|
||||
listDisksLogic :: (Has (Error S9Error) sig m, MonadIO m) => m [AppMgr.DiskInfo]
|
||||
listDisksLogic = runExceptT AppMgr.diskShow >>= liftEither
|
||||
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
module Handler.Network where
|
||||
|
||||
import Startlude hiding ( Reader
|
||||
, ask
|
||||
, asks
|
||||
, runReader
|
||||
)
|
||||
|
||||
import Control.Carrier.Lift ( runM )
|
||||
import Control.Effect.Error
|
||||
import Control.Carrier.Reader
|
||||
import Lib.Error
|
||||
import Yesod.Core ( getYesod )
|
||||
|
||||
import Control.Carrier.Reader ( runReader )
|
||||
import Control.Effect.Labelled ( runLabelled )
|
||||
import Control.Effect.Reader.Labelled
|
||||
import Foundation
|
||||
import qualified Lib.Algebra.Domain.AppMgr as AppMgr2
|
||||
import Lib.Types.Core
|
||||
@@ -18,11 +21,12 @@ import Lib.Types.Core
|
||||
postResetLanR :: Handler ()
|
||||
postResetLanR = do
|
||||
ctx <- getYesod
|
||||
runM . handleS9ErrC . runReader ctx $ postResetLanLogic
|
||||
runM . handleS9ErrC . runReader (appLanThread ctx) . runLabelled @"lanThread" $ postResetLanLogic
|
||||
|
||||
postResetLanLogic :: (MonadIO m, Has (Reader AgentCtx) sig m, Has (Error S9Error) sig m) => m ()
|
||||
postResetLanLogic :: (MonadIO m, HasLabelled "lanThread" (Reader (MVar ThreadId)) sig m, Has (Error S9Error) sig m)
|
||||
=> m ()
|
||||
postResetLanLogic = do
|
||||
threadVar <- asks appLanThread
|
||||
threadVar <- ask @"lanThread"
|
||||
mtid <- liftIO . tryTakeMVar $ threadVar
|
||||
case mtid of
|
||||
Nothing -> throwError $ TemporarilyForbiddenE (AppId "LAN") "reset" "being reset"
|
||||
|
||||
@@ -48,6 +48,7 @@ import System.Process ( callCommand )
|
||||
|
||||
import Constants
|
||||
import Control.Effect.Error hiding ( run )
|
||||
import Control.Effect.Labelled ( runLabelled )
|
||||
import Daemon.ZeroConf ( getStart9AgentHostname )
|
||||
import qualified Data.Text as T
|
||||
import Foundation
|
||||
@@ -438,10 +439,11 @@ syncInstallAppMgr = SyncOp "Install AppMgr" check migrate False
|
||||
Left _ -> pure True
|
||||
Right v -> not . (v <||) <$> asks (appMgrVersionSpec . appSettings)
|
||||
migrate = fmap (either absurd id) . runExceptT . flip catchE failUpdate $ do
|
||||
lan <- asks appLanThread
|
||||
avs <- asks $ appMgrVersionSpec . appSettings
|
||||
av <- AppMgr.installNewAppMgr avs
|
||||
unless (av <|| avs) $ throwE $ AppMgrVersionE av avs
|
||||
postResetLanLogic -- to accommodate 0.2.x -> 0.2.9 where previous appmgr didn't correctly set up lan
|
||||
flip runReaderT lan $ runLabelled @"lanThread" $ postResetLanLogic -- to accommodate 0.2.x -> 0.2.9 where previous appmgr didn't correctly set up lan
|
||||
|
||||
syncUpgradeLifeline :: SyncOp
|
||||
syncUpgradeLifeline = SyncOp "Upgrade Lifeline" check migrate False
|
||||
@@ -583,11 +585,11 @@ syncRestarterService = SyncOp "Install Restarter Service" check migrate True
|
||||
liftIO $ callCommand "systemctl enable restarter.timer"
|
||||
|
||||
syncUpgradeTor :: SyncOp
|
||||
syncUpgradeTor = SyncOp "Install Tor 0.3.5.12-1" check migrate False
|
||||
syncUpgradeTor = SyncOp "Install Tor 0.3.5.14-1" check migrate False
|
||||
where
|
||||
check =
|
||||
liftIO
|
||||
$ ( run (shell [i|dpkg -l|] $| shell [i|grep tor|] $| shell [i|grep 0.3.5.12-1|] $| conduit await)
|
||||
$ ( run (shell [i|dpkg -l|] $| shell [i|grep tor|] $| shell [i|grep 0.3.5.14-1|] $| conduit await)
|
||||
$> False
|
||||
)
|
||||
`catch` \(e :: ProcessException) -> case e of
|
||||
@@ -595,7 +597,7 @@ syncUpgradeTor = SyncOp "Install Tor 0.3.5.12-1" check migrate False
|
||||
_ -> throwIO e
|
||||
migrate = liftIO . run $ do
|
||||
shell "apt-get update"
|
||||
shell "apt-get install -y tor=0.3.5.12-1"
|
||||
shell "apt-get install -y tor=0.3.5.14-1"
|
||||
|
||||
syncDropCertificateUniqueness :: SyncOp
|
||||
syncDropCertificateUniqueness = SyncOp "Eliminate OpenSSL unique_subject=yes" check migrate False
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::os::unix::process::ExitStatusExt;
|
||||
use std::path::Path;
|
||||
|
||||
use argon2::Config;
|
||||
@@ -10,6 +11,7 @@ use serde::Serialize;
|
||||
use crate::util::from_yaml_async_reader;
|
||||
use crate::util::to_yaml_async_writer;
|
||||
use crate::util::Invoke;
|
||||
use crate::util::PersistencePath;
|
||||
use crate::version::VersionT;
|
||||
use crate::Error;
|
||||
use crate::ResultExt;
|
||||
@@ -224,6 +226,28 @@ pub async fn restore_backup<P: AsRef<Path>>(
|
||||
}
|
||||
|
||||
crate::tor::restart().await?;
|
||||
// Delete the fullchain certificate, so it can be regenerated with the restored tor pubkey address
|
||||
PersistencePath::from_ref("apps")
|
||||
.join(&app_id)
|
||||
.join("cert-local.fullchain.crt.pem")
|
||||
.delete()
|
||||
.await?;
|
||||
crate::tor::write_lan_services(
|
||||
&crate::tor::services_map(&PersistencePath::from_ref(crate::SERVICES_YAML)).await?,
|
||||
)
|
||||
.await?;
|
||||
let svc_exit = std::process::Command::new("service")
|
||||
.args(&["nginx", "reload"])
|
||||
.status()?;
|
||||
crate::ensure_code!(
|
||||
svc_exit.success(),
|
||||
crate::error::GENERAL_ERROR,
|
||||
"Failed to Reload Nginx: {}",
|
||||
svc_exit
|
||||
.code()
|
||||
.or_else(|| { svc_exit.signal().map(|a| 128 + a) })
|
||||
.unwrap_or(0)
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -110,6 +110,14 @@ impl PersistencePath {
|
||||
pub async fn for_update(self) -> Result<UpdateHandle<ForRead>, Error> {
|
||||
UpdateHandle::new(self).await
|
||||
}
|
||||
|
||||
pub async fn delete(&self) -> Result<(), Error> {
|
||||
match tokio::fs::remove_file(self.path()).await {
|
||||
Ok(()) => Ok(()),
|
||||
Err(k) if k.kind() == std::io::ErrorKind::NotFound => Ok(()),
|
||||
e => e.with_code(crate::error::FILESYSTEM_ERROR),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<li>Redirecting to HTTPS when navigating to LAN address</li>
|
||||
<li>Displaying warning messages during concurrent upgrades of dependent services</li>
|
||||
<li>Allowing larger file uploads</li>
|
||||
<li>Patching a security fix for Tor</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user