move stream zipping to cli upload

This commit is contained in:
Lucy Cifferello
2022-09-12 14:26:25 -06:00
parent 78ba3e8adc
commit 89ad420a2a
2 changed files with 52 additions and 5 deletions

View File

@@ -12,9 +12,18 @@ module Cli.Cli (
cliMain, cliMain,
) where ) where
import Codec.Archive.Zip.Conduit.Types
import Codec.Archive.Zip.Conduit.Zip (ZipOptions (..), zipFileData, zipStream)
import Conduit ( import Conduit (
ConduitT,
MonadResource,
awaitForever,
foldC, foldC,
runConduit, runConduit,
runResourceT,
sinkHandle,
sinkNull,
yield,
(.|), (.|),
) )
import Control.Monad.Logger ( import Control.Monad.Logger (
@@ -55,6 +64,7 @@ import Data.String.Interpolate.IsString (
i, i,
) )
import Data.Text (toLower) import Data.Text (toLower)
import Data.Time (getTimeZone, utcToLocalTime)
import Dhall ( import Dhall (
Encoder (embed), Encoder (embed),
FromDhall (..), FromDhall (..),
@@ -89,6 +99,7 @@ import Network.HTTP.Simple (
parseRequest, parseRequest,
setRequestBody, setRequestBody,
setRequestBodyJSON, setRequestBodyJSON,
setRequestBodySource,
setRequestHeaders, setRequestHeaders,
setRequestQueryString, setRequestQueryString,
) )
@@ -150,14 +161,15 @@ import Startlude (
IsString (..), IsString (..),
Maybe (..), Maybe (..),
Monad ((>>=)), Monad ((>>=)),
Num (fromInteger),
ReaderT (runReaderT), ReaderT (runReaderT),
Semigroup ((<>)), Semigroup ((<>)),
Show, Show,
String, String,
Word64,
appendFile, appendFile,
const, const,
decodeUtf8, decodeUtf8,
encodeUtf8,
exitWith, exitWith,
filter, filter,
flip, flip,
@@ -167,11 +179,14 @@ import Startlude (
fromIntegral, fromIntegral,
fromMaybe, fromMaybe,
fst, fst,
getCurrentTime,
headMay, headMay,
liftIO,
not, not,
panic, panic,
show, show,
snd, snd,
stdout,
unlessM, unlessM,
void, void,
when, when,
@@ -587,13 +602,16 @@ eosUpload (EosUpload name img version) = do
hash <- hashFile @_ @SHA256 img hash <- hashFile @_ @SHA256 img
bar <- newProgressBar defStyle 30 (Progress 0 (fromIntegral size) ()) bar <- newProgressBar defStyle 30 (Progress 0 (fromIntegral size) ())
body <- observedStreamFile (updateProgress bar . const . sfs2prog) img body <- observedStreamFile (updateProgress bar . const . sfs2prog) img
let r = liftIO $ runResourceT $ runConduit $ (createZipEntry img (Just $ fromIntegral size) .| void (zipStream zipOptions)) .| sinkHandle stdout
let withBody = setRequestBody body noBody let withBody = setRequestBody body noBody
let withQParams = let withQParams =
setRequestQueryString setRequestQueryString
[("version", Just $ show version), ("hash", Just $ convertToBase Base16 hash)] [("version", Just $ show version), ("hash", Just $ convertToBase Base16 hash)]
withBody withBody
let withSource = setRequestBodySource (fromIntegral size) (r) withQParams
manager <- newTlsManager manager <- newTlsManager
res <- runReaderT (httpLbs withQParams) manager res <- runReaderT (httpLbs withSource) manager
if getResponseStatus res == status200 if getResponseStatus res == status200
then -- no output is successful then -- no output is successful
pure () pure ()
@@ -604,6 +622,34 @@ eosUpload (EosUpload name img version) = do
where where
sfs2prog :: StreamFileStatus -> Progress () sfs2prog :: StreamFileStatus -> Progress ()
sfs2prog StreamFileStatus{..} = Progress (fromIntegral readSoFar) (fromIntegral fileSize) () sfs2prog StreamFileStatus{..} = Progress (fromIntegral readSoFar) (fromIntegral fileSize) ()
zipOptions =
ZipOptions
{ zipOpt64 = True
, zipOptCompressLevel = 0
, zipOptInfo = ZipInfo{zipComment = encodeUtf8 "zipped eos image"}
}
createZipEntry ::
MonadResource m =>
FilePath ->
Maybe Word64 ->
ConduitT () (ZipEntry, ZipData m) m ()
createZipEntry path size = do
let d = zipFileData img
utcTime <- liftIO getCurrentTime
localTimeZone <- liftIO $ getTimeZone utcTime
let zipEntry =
ZipEntry
{ zipEntryName = Right $ encodeUtf8 $ show path
, zipEntryTime = utcToLocalTime localTimeZone utcTime
, zipEntrySize = size
, zipEntryExternalAttributes = Nothing
}
yield (zipEntry, d)
_yieldFinal :: Monad m => ConduitT (ZipEntry, ZipData m) B8.ByteString m Word64 -> ConduitT () B8.ByteString m ()
_yieldFinal consumer = awaitForever $ \_ -> do
yield consumer .| sinkNull
index :: String -> String -> Version -> IO () index :: String -> String -> Version -> IO ()

View File

@@ -21,7 +21,7 @@ import Codec.Archive.Zip.Conduit.Zip (
import Conduit ( import Conduit (
ConduitT, ConduitT,
MonadUnliftIO, MonadUnliftIO,
fuseBoth, fuseUpstream,
runConduit, runConduit,
sinkFile, sinkFile,
sinkFileBS, sinkFileBS,
@@ -214,12 +214,13 @@ postEosUploadR = do
hash <- case maybeHash of hash <- case maybeHash of
Nothing -> sendResponseStatus status400 ("Missing Hash" :: Text) Nothing -> sendResponseStatus status400 ("Missing Hash" :: Text)
Just h -> pure h Just h -> pure h
(maybeSize :: Maybe Word64) <- maybeM (pure Nothing) (pure . readMaybe . decodeUtf8) (lookupHeader "Content-Length") -- (maybeSize :: Maybe Word64) <- maybeM (pure Nothing) (pure . readMaybe . decodeUtf8) (lookupHeader "Content-Length")
resourcesTemp <- getsYesod $ (</> "temp") . resourcesDir . appSettings resourcesTemp <- getsYesod $ (</> "temp") . resourcesDir . appSettings
createDirectoryIfMissing True resourcesTemp createDirectoryIfMissing True resourcesTemp
withTempDirectory resourcesTemp "neweos" $ \dir -> do withTempDirectory resourcesTemp "neweos" $ \dir -> do
let path = dir </> "eos" <.> "img" let path = dir </> "eos" <.> "img"
void . runConduit $ createZipEntry path maybeSize rawRequestBody .| (zipStream zipOptions `fuseBoth` sinkFileBS path) runConduit $ rawRequestBody .| sinkFile path
-- void . runConduit $ createZipEntry path maybeSize rawRequestBody .| (zipStream zipOptions `fuseUpstream` sinkFileBS path)
void . runDB $ upsert (EosHash version hash) [EosHashHash =. hash] void . runDB $ upsert (EosHash version hash) [EosHashHash =. hash]
let targetPath = root </> show version let targetPath = root </> show version
removePathForcibly targetPath removePathForcibly targetPath