mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-05-11 08:16:57 +00:00
Merge branch 'master' into f/xftp-non-tmp-error
This commit is contained in:
@@ -105,7 +105,7 @@ apt update && apt install openssl
|
||||
|
||||
#### Using Docker
|
||||
|
||||
On Linux, you can deploy smp server using Docker. This will download image from [Docker Hub](https://hub.docker.com/r/simplexchat/simplexmq).
|
||||
On Linux, you can deploy smp server using Docker. This will download image from [Docker Hub](https://hub.docker.com/r/simplexchat/smp-server).
|
||||
|
||||
1. Create `config` and `logs` directories:
|
||||
|
||||
@@ -121,7 +121,7 @@ On Linux, you can deploy smp server using Docker. This will download image from
|
||||
-p 5223:5223 \
|
||||
-v $HOME/simplex/config:/etc/opt/simplex:z \
|
||||
-v $HOME/simplex/logs:/var/opt/simplex:z \
|
||||
simplexchat/simplexmq:latest
|
||||
simplexchat/smp-server:latest
|
||||
```
|
||||
|
||||
#### Ubuntu
|
||||
|
||||
+10
-5
@@ -1,10 +1,10 @@
|
||||
FROM ubuntu:focal AS final
|
||||
FROM ubuntu:focal AS build
|
||||
FROM ubuntu:22.04 AS final
|
||||
FROM ubuntu:22.04 AS build
|
||||
|
||||
### Build stage
|
||||
|
||||
# Install curl and git and smp-related dependencies
|
||||
RUN apt-get update && apt-get install -y curl git build-essential libgmp3-dev zlib1g-dev llvm llvm-dev libnuma-dev
|
||||
RUN apt-get update && apt-get install -y curl git build-essential libgmp3-dev zlib1g-dev llvm-12 llvm-12-dev libnuma-dev
|
||||
|
||||
# Install ghcup
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_GHC_VERSION=8.10.7 BOOTSTRAP_HASKELL_CABAL_VERSION=3.6.2.0 sh
|
||||
@@ -21,7 +21,12 @@ WORKDIR /project
|
||||
|
||||
# Compile smp-server
|
||||
RUN cabal update
|
||||
RUN cabal install
|
||||
RUN cabal build exe:smp-server
|
||||
|
||||
# Strip the binary from debug symbols to reduce size
|
||||
RUN smp=$(find ./dist-newstyle -name "smp-server" -type f -executable) && \
|
||||
mv "$smp" ./ && \
|
||||
strip ./smp-server
|
||||
|
||||
### Final stage
|
||||
|
||||
@@ -31,7 +36,7 @@ FROM final
|
||||
RUN apt-get update && apt-get install -y openssl libnuma-dev
|
||||
|
||||
# Copy compiled smp-server from build stage
|
||||
COPY --from=build /root/.cabal/bin/smp-server /usr/bin/smp-server
|
||||
COPY --from=build /project/smp-server /usr/bin/smp-server
|
||||
|
||||
# Copy our helper script
|
||||
COPY ./scripts/docker/entrypoint /usr/bin/entrypoint
|
||||
|
||||
@@ -3,6 +3,8 @@ FROM ubuntu:focal
|
||||
# Install curl
|
||||
RUN apt-get update && apt-get install -y curl
|
||||
|
||||
ARG version=undefined
|
||||
|
||||
# Download latest smp-server release and assign executable permission
|
||||
RUN curl -L https://github.com/simplex-chat/simplexmq/releases/latest/download/smp-server-ubuntu-20_04-x86-64 -o /usr/bin/smp-server && \
|
||||
chmod +x /usr/bin/smp-server
|
||||
|
||||
@@ -20,10 +20,9 @@ if [ ! -f "$confd/smp-server.ini" ]; then
|
||||
fi
|
||||
|
||||
# backup store log
|
||||
[ -f "$logd/smp-server-store.log" ] && cp "$logd"/smp-server-store.log "$logd"/smp-server-store.log.bak
|
||||
# rotate server log
|
||||
[ -f "$logd/smp-server.log" ] && mv "$logd"/smp-server.log "$logd"/smp-server-"$(date +'%FT%T')".log
|
||||
[ -f "$logd/smp-server-store.log" ] && cp "$logd"/smp-server-store.log "$logd"/smp-server-store.log."$(date +'%FT%T')"
|
||||
|
||||
# Finally, run smp-sever. Notice that "exec" here is important:
|
||||
# smp-server replaces our helper script, so that it can catch INT signal
|
||||
exec smp-server start > "$logd"/smp-server.log 2>&1
|
||||
exec smp-server start +RTS -N -RTS
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ import Simplex.Messaging.Encoding.String
|
||||
import Simplex.Messaging.Protocol (EntityId, XFTPServer, XFTPServerWithAuth)
|
||||
import Simplex.Messaging.TMap (TMap)
|
||||
import qualified Simplex.Messaging.TMap as TM
|
||||
import Simplex.Messaging.Util (liftError, liftIOEither, tshow, whenM)
|
||||
import Simplex.Messaging.Util (liftError, liftIOEither, tshow, unlessM, whenM)
|
||||
import System.FilePath (takeFileName, (</>))
|
||||
import UnliftIO
|
||||
import UnliftIO.Concurrent
|
||||
@@ -273,9 +273,9 @@ runXFTPRcvLocalWorker c doWork = do
|
||||
getChunkPaths (RcvFileChunk {chunkTmpPath = Nothing} : _cs) =
|
||||
throwError $ INTERNAL "no chunk path"
|
||||
|
||||
deleteRcvFile :: AgentMonad m => AgentClient -> UserId -> RcvFileId -> m ()
|
||||
deleteRcvFile c userId rcvFileEntityId = do
|
||||
RcvFile {rcvFileId, prefixPath, status} <- withStore c $ \db -> getRcvFileByEntityId db userId rcvFileEntityId
|
||||
deleteRcvFile :: AgentMonad m => AgentClient -> RcvFileId -> m ()
|
||||
deleteRcvFile c rcvFileEntityId = do
|
||||
RcvFile {rcvFileId, prefixPath, status} <- withStore c $ \db -> getRcvFileByEntityId db rcvFileEntityId
|
||||
if status == RFSComplete || status == RFSError
|
||||
then do
|
||||
removePath prefixPath
|
||||
@@ -480,6 +480,7 @@ runXFTPSndWorker c srv doWork = do
|
||||
uploadFileChunk sndFileChunk@SndFileChunk {sndFileId, userId, chunkSpec = chunkSpec@XFTPChunkSpec {filePath}, digest = chunkDigest} replica = do
|
||||
replica'@SndFileChunkReplica {sndChunkReplicaId} <- addRecipients sndFileChunk replica
|
||||
fsFilePath <- toFSFilePath filePath
|
||||
unlessM (doesFileExist fsFilePath) $ throwError $ INTERNAL "encrypted file doesn't exist on upload"
|
||||
let chunkSpec' = chunkSpec {filePath = fsFilePath} :: XFTPChunkSpec
|
||||
atomically $ assertAgentForeground c
|
||||
agentXFTPUploadChunk c userId chunkDigest replica' chunkSpec'
|
||||
@@ -572,9 +573,9 @@ runXFTPSndWorker c srv doWork = do
|
||||
chunkUploaded SndFileChunk {replicas} =
|
||||
any (\SndFileChunkReplica {replicaStatus} -> replicaStatus == SFRSUploaded) replicas
|
||||
|
||||
deleteSndFileInternal :: AgentMonad m => AgentClient -> UserId -> SndFileId -> m ()
|
||||
deleteSndFileInternal c userId sndFileEntityId = do
|
||||
SndFile {sndFileId, prefixPath, status} <- withStore c $ \db -> getSndFileByEntityId db userId sndFileEntityId
|
||||
deleteSndFileInternal :: AgentMonad m => AgentClient -> SndFileId -> m ()
|
||||
deleteSndFileInternal c sndFileEntityId = do
|
||||
SndFile {sndFileId, prefixPath, status} <- withStore c $ \db -> getSndFileByEntityId db sndFileEntityId
|
||||
if status == SFSComplete || status == SFSError
|
||||
then do
|
||||
forM_ prefixPath $ removePath <=< toFSFilePath
|
||||
@@ -583,7 +584,7 @@ deleteSndFileInternal c userId sndFileEntityId = do
|
||||
|
||||
deleteSndFileRemote :: forall m. AgentMonad m => AgentClient -> UserId -> SndFileId -> ValidFileDescription 'FSender -> m ()
|
||||
deleteSndFileRemote c userId sndFileEntityId (ValidFileDescription FileDescription {chunks}) = do
|
||||
deleteSndFileInternal c userId sndFileEntityId `catchError` (notify c sndFileEntityId . SFERR)
|
||||
deleteSndFileInternal c sndFileEntityId `catchError` (notify c sndFileEntityId . SFERR)
|
||||
forM_ chunks $ \ch -> deleteFileChunk ch `catchError` (notify c sndFileEntityId . SFERR)
|
||||
where
|
||||
deleteFileChunk :: FileChunk -> m ()
|
||||
|
||||
@@ -345,16 +345,16 @@ xftpReceiveFile :: AgentErrorMonad m => AgentClient -> UserId -> ValidFileDescri
|
||||
xftpReceiveFile c = withAgentEnv c .: receiveFile c
|
||||
|
||||
-- | Delete XFTP rcv file (deletes work files from file system and db records)
|
||||
xftpDeleteRcvFile :: AgentErrorMonad m => AgentClient -> UserId -> RcvFileId -> m ()
|
||||
xftpDeleteRcvFile c = withAgentEnv c .: deleteRcvFile c
|
||||
xftpDeleteRcvFile :: AgentErrorMonad m => AgentClient -> RcvFileId -> m ()
|
||||
xftpDeleteRcvFile c = withAgentEnv c . deleteRcvFile c
|
||||
|
||||
-- | Send XFTP file
|
||||
xftpSendFile :: AgentErrorMonad m => AgentClient -> UserId -> FilePath -> Int -> m SndFileId
|
||||
xftpSendFile c = withAgentEnv c .:. sendFile c
|
||||
|
||||
-- | Delete XFTP snd file internally (deletes work files from file system and db records)
|
||||
xftpDeleteSndFileInternal :: AgentErrorMonad m => AgentClient -> UserId -> SndFileId -> m ()
|
||||
xftpDeleteSndFileInternal c = withAgentEnv c .: deleteSndFileInternal c
|
||||
xftpDeleteSndFileInternal :: AgentErrorMonad m => AgentClient -> SndFileId -> m ()
|
||||
xftpDeleteSndFileInternal c = withAgentEnv c . deleteSndFileInternal c
|
||||
|
||||
-- | Delete XFTP snd file chunks on servers
|
||||
xftpDeleteSndFileRemote :: AgentErrorMonad m => AgentClient -> UserId -> SndFileId -> ValidFileDescription 'FSender -> m ()
|
||||
|
||||
@@ -1888,15 +1888,15 @@ createRcvFile db gVar userId fd@FileDescription {chunks} prefixPath tmpPath save
|
||||
"INSERT INTO rcv_file_chunk_replicas (replica_number, rcv_file_chunk_id, xftp_server_id, replica_id, replica_key) VALUES (?,?,?,?,?)"
|
||||
(replicaNo, chunkId, srvId, replicaId, replicaKey)
|
||||
|
||||
getRcvFileByEntityId :: DB.Connection -> UserId -> RcvFileId -> IO (Either StoreError RcvFile)
|
||||
getRcvFileByEntityId db userId rcvFileEntityId = runExceptT $ do
|
||||
rcvFileId <- ExceptT $ getRcvFileIdByEntityId_ db userId rcvFileEntityId
|
||||
getRcvFileByEntityId :: DB.Connection -> RcvFileId -> IO (Either StoreError RcvFile)
|
||||
getRcvFileByEntityId db rcvFileEntityId = runExceptT $ do
|
||||
rcvFileId <- ExceptT $ getRcvFileIdByEntityId_ db rcvFileEntityId
|
||||
ExceptT $ getRcvFile db rcvFileId
|
||||
|
||||
getRcvFileIdByEntityId_ :: DB.Connection -> UserId -> RcvFileId -> IO (Either StoreError DBRcvFileId)
|
||||
getRcvFileIdByEntityId_ db userId rcvFileEntityId =
|
||||
getRcvFileIdByEntityId_ :: DB.Connection -> RcvFileId -> IO (Either StoreError DBRcvFileId)
|
||||
getRcvFileIdByEntityId_ db rcvFileEntityId =
|
||||
firstRow fromOnly SEFileNotFound $
|
||||
DB.query db "SELECT rcv_file_id FROM rcv_files WHERE user_id = ? AND rcv_file_entity_id = ?" (userId, rcvFileEntityId)
|
||||
DB.query db "SELECT rcv_file_id FROM rcv_files WHERE rcv_file_entity_id = ?" (Only rcvFileEntityId)
|
||||
|
||||
getRcvFile :: DB.Connection -> DBRcvFileId -> IO (Either StoreError RcvFile)
|
||||
getRcvFile db rcvFileId = runExceptT $ do
|
||||
@@ -2115,15 +2115,15 @@ createSndFile db gVar userId numRecipients path prefixPath key nonce =
|
||||
"INSERT INTO snd_files (snd_file_entity_id, user_id, num_recipients, key, nonce, path, prefix_path, status) VALUES (?,?,?,?,?,?,?,?)"
|
||||
(sndFileEntityId, userId, numRecipients, key, nonce, path, prefixPath, SFSNew)
|
||||
|
||||
getSndFileByEntityId :: DB.Connection -> UserId -> SndFileId -> IO (Either StoreError SndFile)
|
||||
getSndFileByEntityId db userId sndFileEntityId = runExceptT $ do
|
||||
sndFileId <- ExceptT $ getSndFileIdByEntityId_ db userId sndFileEntityId
|
||||
getSndFileByEntityId :: DB.Connection -> SndFileId -> IO (Either StoreError SndFile)
|
||||
getSndFileByEntityId db sndFileEntityId = runExceptT $ do
|
||||
sndFileId <- ExceptT $ getSndFileIdByEntityId_ db sndFileEntityId
|
||||
ExceptT $ getSndFile db sndFileId
|
||||
|
||||
getSndFileIdByEntityId_ :: DB.Connection -> UserId -> SndFileId -> IO (Either StoreError DBSndFileId)
|
||||
getSndFileIdByEntityId_ db userId sndFileEntityId =
|
||||
getSndFileIdByEntityId_ :: DB.Connection -> SndFileId -> IO (Either StoreError DBSndFileId)
|
||||
getSndFileIdByEntityId_ db sndFileEntityId =
|
||||
firstRow fromOnly SEFileNotFound $
|
||||
DB.query db "SELECT snd_file_id FROM snd_files WHERE user_id = ? AND snd_file_entity_id = ?" (userId, sndFileEntityId)
|
||||
DB.query db "SELECT snd_file_id FROM snd_files WHERE snd_file_entity_id = ?" (Only sndFileEntityId)
|
||||
|
||||
getSndFile :: DB.Connection -> DBSndFileId -> IO (Either StoreError SndFile)
|
||||
getSndFile db sndFileId = runExceptT $ do
|
||||
|
||||
+2
-2
@@ -86,7 +86,7 @@ testXFTPAgentSendReceive = withXFTPServer $ do
|
||||
sndr <- getSMPAgentClient' agentCfg initAgentServers testDB
|
||||
(rfd1, rfd2) <- runRight $ do
|
||||
(sfId, _, rfd1, rfd2) <- testSend sndr filePath
|
||||
xftpDeleteSndFileInternal sndr 1 sfId
|
||||
xftpDeleteSndFileInternal sndr sfId
|
||||
pure (rfd1, rfd2)
|
||||
|
||||
-- receive file, delete rcv file
|
||||
@@ -97,7 +97,7 @@ testXFTPAgentSendReceive = withXFTPServer $ do
|
||||
rcp <- getSMPAgentClient' agentCfg initAgentServers testDB
|
||||
runRight_ $ do
|
||||
rfId <- testReceive rcp rfd originalFilePath
|
||||
xftpDeleteRcvFile rcp 1 rfId
|
||||
xftpDeleteRcvFile rcp rfId
|
||||
|
||||
createRandomFile :: IO FilePath
|
||||
createRandomFile = do
|
||||
|
||||
Reference in New Issue
Block a user