cloudy-0.1.0.0: src/Cloudy/Cmd/CopyFile.hs
{-# LANGUAGE OverloadedRecordDot #-}
module Cloudy.Cmd.CopyFile where
import Cloudy.Cli (CopyFileCliOpts (..), CopyFileDirection (..), Recursive (..))
import Cloudy.Cmd.Utils (SelectInstBy, findInstanceInfoForSelectInstBy, mkSelectInstBy)
import Cloudy.LocalConfFile (LocalConfFileOpts (..))
import Cloudy.Db (withCloudyDb, InstanceInfo (..), ScalewayInstance (..))
import Data.Text (unpack, Text)
import Data.Void (absurd)
import System.Posix.Process (executeFile)
import Control.Monad (when)
import Control.FromSum (fromMaybeM)
data CopyFileSettings = CopyFileSettings
{ selectInstBy :: SelectInstBy
, direction :: CopyFileDirection
, recursive :: Recursive
, filesToCopyArgs :: [Text]
}
deriving stock Show
mkSettings :: LocalConfFileOpts -> CopyFileCliOpts -> IO CopyFileSettings
mkSettings _localConfFileOpts cliOpts = do
selectInstBy <- mkSelectInstBy cliOpts.id cliOpts.name
pure
CopyFileSettings
{ selectInstBy
, direction = cliOpts.direction
, recursive = cliOpts.recursive
, filesToCopyArgs = cliOpts.filesToCopyArgs
}
runCopyFile :: LocalConfFileOpts -> CopyFileCliOpts -> IO ()
runCopyFile localConfFileOpts cliOpts = do
settings <- mkSettings localConfFileOpts cliOpts
ipAddr <- withCloudyDb $ \conn -> do
instanceInfo <- findInstanceInfoForSelectInstBy conn settings.selectInstBy
case instanceInfo of
CloudyAwsInstance _cloudyInstance void -> absurd void
CloudyScalewayInstance _cloudyInstance scalewayInstance -> pure scalewayInstance.scalewayIpAddress
when (length settings.filesToCopyArgs <= 1) $
error "ERROR: must pass at least 2 files"
(firstFiles, lastFile) <-
fromMaybeM
(error "ERROR: unsnoc should have succeeded since we check there are at least 2 files")
(unsnoc settings.filesToCopyArgs)
let recursiveArg =
case settings.recursive of
Recursive -> ["-r"]
NoRecursive -> []
scpFilesArgs =
case settings.direction of
FromInstanceToLocal ->
fmap (\file -> "root@" <> ipAddr <> ":" <> file) firstFiles <>
[lastFile]
ToInstanceFromLocal -> firstFiles <> ["root@" <> ipAddr <> ":" <> lastFile]
scpArgs =
fmap unpack $ recursiveArg <> scpFilesArgs
putStrLn $ "About to run scp command: " <> show ("scp" : scpArgs)
executeFile "scp" True scpArgs Nothing
-- TODO: Available from Data.List in GHC-9.8
unsnoc :: [a] -> Maybe ([a], a)
unsnoc = foldr (\x -> Just . maybe ([], x) (\(~(a, b)) -> (x : a, b))) Nothing