Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server side #272

Merged
merged 104 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
a3c9530
remote: heavy lifting
sorki Nov 30, 2023
e700c72
remote: Remote.Protocol -> Remote.Client
sorki Nov 30, 2023
3e135c1
remote: neaten MonadStore
sorki Nov 30, 2023
aaf0567
remote: add Remote.GADT
sorki Nov 30, 2023
cbbc731
remote: fix mapStoreConfig import
sorki Nov 30, 2023
936fdf8
remote: Data.Serializer, expand signature of mapIso/mapPrism*
sorki Dec 1, 2023
ec79cfe
remote: NixSerializer, move maybePath from where clause, expose
sorki Dec 1, 2023
e57397b
remote: move ourProtoVersion near type, elaborate Types imports in Cl…
sorki Dec 1, 2023
78639b8
remote: NixSerializer, rename mapError to mapErrorST, add mapErrorS, …
sorki Dec 1, 2023
2c46d34
remote, LoggerOpCode Int -> Word64
sorki Dec 1, 2023
c5f3c1e
remote: generalize error in sockPutS, sockGetS, add Types.WorkerMagic…
sorki Dec 1, 2023
e0456e3
remote: prefix WorkerOp, add workerOp Serializer, test
sorki Dec 1, 2023
7f9c7fb
remote: add/derive instances for StoreRequest
sorki Dec 1, 2023
0ab79e5
remote: add Types.StoreText, use in AddTextToStore
sorki Dec 1, 2023
ee172f0
remote: add TestStoreConfig
sorki Dec 1, 2023
dbc118f
docs/contributors: add ryantrinkle
sorki Dec 1, 2023
fcbcafa
remote: GADT -> Types.StoreRequest
sorki Dec 1, 2023
b2c31e0
remote: recursive Bool -> FileIngestionMethod
sorki Dec 1, 2023
c3ece67
core: add note that parseDerivedPath breaks when storeDir has exclama…
sorki Dec 1, 2023
91befa2
core: fix parseDerivedPath breaking when StoreDir contains exclamatio…
sorki Dec 1, 2023
4e224c3
tests: custom Arbitrary OutputsSpec producing nonempty OutputsSpec_Names
sorki Dec 1, 2023
4ae2d82
remote: add storeRequest Serializer, property test
sorki Dec 1, 2023
6c0edf2
remote: drop dependent-sum upper bound like in core
sorki Dec 1, 2023
cc931dd
tests: custom Arbitrary UTCTime instance, drop quickcheck-instances
sorki Dec 2, 2023
a7fbcf7
tests: custom Arbitrary BuildResult without Just mempty errorMessage
sorki Dec 2, 2023
c815068
tests: add custom Arbitrary (Maybe Text) that doesn't generate Just m…
sorki Dec 2, 2023
9fb7854
tests: custom Arbitrary Trace and Arbitrary ErrorInfo w/o (Just 0)
sorki Dec 2, 2023
d8df1cc
remote: no more hacks for StoreRequest prop
sorki Dec 2, 2023
4adf509
temp: add source-repository-package override for dependent-sum-template
sorki Dec 2, 2023
14f93bf
remote: add Types.TrusteFlag, serializer, use in client, more props f…
sorki Dec 2, 2023
d555768
remote: handshake - use minimumCommonVersion of our vs daemon protoVe…
sorki Dec 2, 2023
a8a4d66
remote: protoVersion_minor 21 -> 24
sorki Dec 2, 2023
ea49946
remote: add preStoreConfigToStoreConfig, use in handshake
sorki Dec 2, 2023
a05377a
remote: add Types.Handshake, use as a greeting result
sorki Dec 2, 2023
8b1db17
remote: add Types.Query.Missing for QueryMissing result
sorki Dec 2, 2023
265d252
core: split signature/narSignature parser/builder
sorki Dec 2, 2023
6074504
remote: change AddSignatures from [ByteString] to Set Signature
sorki Dec 2, 2023
217ea1b
remote: add CollectGarbage StoreRequest
sorki Dec 2, 2023
bc98de1
remote: drop MonadRemote* store aliases
sorki Dec 3, 2023
c0a17f2
remote: MonadRemoteStore typeclass
sorki Dec 3, 2023
a39ee89
remote: init Remote.Server
sorki Dec 2, 2023
9b66373
remote: fix arbitrary repair mode of AddToStore AddTextToStore to Don…
sorki Dec 3, 2023
11a9bff
remote: align AddToStore and AddTextToStore serializers with old vers…
sorki Dec 3, 2023
638ac9e
remote: fix dumm(p)y path typo
sorki Dec 3, 2023
0c54337
remote: add NarSource to RemoteStoreState, add setNarSource, takeNarS…
sorki Dec 3, 2023
c25a5a8
remote: init Remote.Client.doReq
sorki Dec 3, 2023
a934eb1
remote: MonadRemoteStoreR
sorki Dec 3, 2023
001f4ca
remote: deal with logger, tagless
sorki Dec 3, 2023
5d927d3
remote: handle logger errors properly
sorki Dec 3, 2023
c4315f1
remote: handle IOExceptions in sockGet8
sorki Dec 3, 2023
6ebc2fc
remote: handle errors in genericIncremental
sorki Dec 3, 2023
f1f30af
remote: also include what was parsed (via Show) in incremental parser…
sorki Dec 3, 2023
82262a1
remote: Client, no more need for nested runRemoteStoreT
sorki Dec 3, 2023
57cc9e3
remote: implement Logger_Read
sorki Dec 3, 2023
6755819
remote: implement Logger_Write
sorki Dec 3, 2023
b506f1a
remote: use DList Logger
sorki Dec 3, 2023
2443d38
remote: pretty doReq, add haddock
sorki Dec 4, 2023
218689d
remote: add RequestSError, shave off undefineds
sorki Dec 4, 2023
de15745
remote: add ReplySError, RemoteStoreError_SerializerReply
sorki Dec 4, 2023
497d0f6
remote: move StoreReply to Types.StoreReply
sorki Dec 4, 2023
d3c9bc3
remote: fix buildResult whitespace
sorki Dec 4, 2023
fb1bcfd
prefix BuildResult fields
sorki Dec 4, 2023
a8077c5
prefix Metadata fields
sorki Dec 4, 2023
2cd4c32
tests: custom Arbitrary Metadata instance with forced SHA256 metadata…
sorki Dec 4, 2023
8936300
core,remote: add OldBuildResult as it is the one we claim to support now
sorki Dec 4, 2023
f93b21c
remote: maybe _ id -> fromMaybe _
sorki Dec 4, 2023
569e68f
remote: drop no longer needed OverloadedStrings from Client
sorki Dec 4, 2023
0693581
core: makeStorePathName -> mkStorePathName
sorki Dec 4, 2023
9cf2e1a
core: split name part errors from InvalidPathError to InvalidNameError
sorki Dec 5, 2023
70443c8
core: improve mkStorePathName and its errors, add test
sorki Dec 5, 2023
b8294ff
core: split parseNameText from mkStorePathName
sorki Dec 5, 2023
2f73cd9
core: add System.Nix.OutputName
sorki Dec 5, 2023
25778c1
core: add System.Nix.Realisation
sorki Dec 5, 2023
72de93d
core: improve haddocks for Build, use trailing haddocks for records
sorki Dec 5, 2023
225b4d3
tests: limit the size of list for OutputName, StorePath name generators
sorki Dec 5, 2023
ee4ad7b
add builtOutputs to BuildResult, more legwork
sorki Dec 5, 2023
e6ed8f8
single BuildResult to rule them all
sorki Dec 5, 2023
1bda8fd
add derivationOutput(Parser|Builder), prop
sorki Dec 5, 2023
9c407cb
init hnix-store-json
sorki Dec 6, 2023
f79effe
remote: fix handling of BuildResult.builtOutputs
sorki Dec 6, 2023
e6d21c1
remote: deal with Realisation.id (required for the server side and qc…
sorki Dec 6, 2023
496fb32
make DerivationOutput explicitely generic
sorki Dec 6, 2023
69060ec
docs/contributors: add andreabedini
sorki Dec 6, 2023
0323bf0
drop dependent-sum-template source-repository-package, add >= 0.2.0.1…
sorki Dec 6, 2023
c8d9789
overlay.nix: dependent-sum-template 0.2.0.1
sorki Dec 6, 2023
bdce1a3
tests: enable TypeFamilies for Realisation
sorki Dec 6, 2023
aa94d3c
remote: separate (Client|Server)Handshake(Input|Output) types
sorki Dec 7, 2023
7dc5c59
tests: add/move Test.Hspec.Nix.forceRight from json
sorki Dec 7, 2023
428a61a
remote: split runStoreSocket, doReq into Remote.Client.Core
sorki Dec 7, 2023
7bdbab9
remote: move enum tests to EnumSpec
sorki Dec 7, 2023
a5dac6d
remote: shuffle reply serializers, extend ReplySError
sorki Dec 7, 2023
5aa62fd
remote: NarSource not in GADT pans out
sorki Dec 7, 2023
77fe9f9
remote: add gcResult serializer
sorki Dec 7, 2023
c841f93
remote: align GC(Options|Result) record field naming
sorki Dec 7, 2023
d18a014
remote: add Query.Missing serializer
sorki Dec 7, 2023
48697e1
remote: add maybePathMetadata serializer
sorki Dec 7, 2023
04a38e8
remote: add opSuccess serializer for StoreReply ()
sorki Dec 7, 2023
774590e
remote: add StoreReply (HashSet StorePath) & StoreReply (HashSet Stor…
sorki Dec 7, 2023
ddfdb89
remote: add GCRoot type, serializer, prop
sorki Dec 7, 2023
523e490
remote: port all operations to GADT based ones
sorki Dec 7, 2023
28d279b
remote: delete obsolete funs from Socket
sorki Dec 7, 2023
4123d96
remote: delete obsolete serialization prims and instances
sorki Dec 7, 2023
b7a9f91
remote: sort Serializer imports
sorki Dec 7, 2023
e5c1492
remote: tests-io cleanup
sorki Dec 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ benchmarks: true
packages:
./hnix-store-core/hnix-store-core.cabal
./hnix-store-db/hnix-store-db.cabal
./hnix-store-json/hnix-store-json.cabal
./hnix-store-nar/hnix-store-nar.cabal
./hnix-store-readonly/hnix-store-readonly.cabal
./hnix-store-remote/hnix-store-remote.cabal
Expand Down
3 changes: 3 additions & 0 deletions cabal.project.local.ci
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ package hnix-store-core
package hnix-store-db
ghc-options: -Wunused-packages -Wall -Werror

package hnix-store-json
ghc-options: -Wunused-packages -Wall -Werror

package hnix-store-nar
ghc-options: -Wunused-packages -Wall -Werror

Expand Down
1 change: 1 addition & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ in {
inherit (haskellPackages)
hnix-store-core
hnix-store-db
hnix-store-json
hnix-store-nar
hnix-store-readonly
hnix-store-remote
Expand Down
3 changes: 3 additions & 0 deletions docs/01-Contributors.org
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ in order of appearance:
+ Luigy Leon @luigy
+ squalus @squalus
+ Vaibhav Sagar @vaibhavsagar
+ Ryan Trinkle @ryantrinkle
+ Travis Whitaker @TravisWhitaker
+ Andrea Bedini @andreabedini
6 changes: 6 additions & 0 deletions hie.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ cradle:
- path: "./hnix-store-db/tests"
component: "hnix-store-db:test:db"

- path: "./hnix-store-json/src"
component: "lib:hnix-store-json"

- path: "./hnix-store-json/tests"
component: "hnix-store-json:test:json"

- path: "./hnix-store-nar/src"
component: "lib:hnix-store-nar"

Expand Down
1 change: 1 addition & 0 deletions hnix-store-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Next

* Changes:
* `System.Nix.StorePath.makeStorePathName` renamed to `System.Nix.StorePath.mkStorePathName`
* `System.Nix.ReadOnlyStore` moved to `hnix-store-readonly` package
and renamed to `System.Nix.Store.ReadOnly` [#247](https://github.com/haskell-nix/hnix-store/pull/247)
* `System.Nix.Nar*` moved to `hnix-store-nar` package [#247](https://github.com/haskell-nix/hnix-store/pull/247)
Expand Down
5 changes: 4 additions & 1 deletion hnix-store-core/hnix-store-core.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ library
, System.Nix.Fingerprint
, System.Nix.Hash
, System.Nix.Hash.Truncation
, System.Nix.OutputName
, System.Nix.Realisation
, System.Nix.Signature
, System.Nix.Store.Types
, System.Nix.StorePath
Expand All @@ -80,7 +82,7 @@ library
, crypton
, data-default-class
, dependent-sum > 0.7
, dependent-sum-template > 0.1.1 && < 0.3
, dependent-sum-template >= 0.2.0.1 && < 0.3
, filepath
, hashable
-- Required for crypton low-level type convertion
Expand All @@ -102,6 +104,7 @@ test-suite core
Fingerprint
Hash
Signature
StorePath
hs-source-dirs:
tests
build-tool-depends:
Expand Down
63 changes: 36 additions & 27 deletions hnix-store-core/src/System/Nix/Build.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,40 @@ Maintainer : srk <[email protected]>
module System.Nix.Build
( BuildMode(..)
, BuildStatus(..)
, BuildResult(..)
, buildSuccess
, BuildResult(..)
) where

import Data.Map (Map)
import Data.Time (UTCTime)
import Data.Text (Text)
import GHC.Generics (Generic)

-- keep the order of these Enums to match enums from reference implementations
import System.Nix.OutputName (OutputName)
import System.Nix.Realisation (DerivationOutput, Realisation)

-- | Mode of the build operation
-- Keep the order of these Enums to match enums from reference implementations
-- src/libstore/store-api.hh
data BuildMode
= BuildMode_Normal
| BuildMode_Repair
| BuildMode_Check
= BuildMode_Normal -- ^ Perform normal build
| BuildMode_Repair -- ^ Try to repair corrupted or missing paths by re-building or re-downloading them
| BuildMode_Check -- ^ Check if the build is reproducible (rebuild and compare to previous build)
deriving (Eq, Generic, Ord, Enum, Show)

-- | Build result status
data BuildStatus =
BuildStatus_Built
| BuildStatus_Substituted
| BuildStatus_AlreadyValid
BuildStatus_Built -- ^ Build performed successfully
| BuildStatus_Substituted -- ^ Path substituted from cache
| BuildStatus_AlreadyValid -- ^ Path is already valid (available in local store)
| BuildStatus_PermanentFailure
| BuildStatus_InputRejected
| BuildStatus_OutputRejected
| BuildStatus_TransientFailure -- possibly transient
| BuildStatus_CachedFailure -- no longer used
| BuildStatus_TimedOut
| BuildStatus_TransientFailure -- ^ Possibly transient build failure
| BuildStatus_CachedFailure -- ^ Obsolete
| BuildStatus_TimedOut -- ^ Build timed out
| BuildStatus_MiscFailure
| BuildStatus_DependencyFailed
| BuildStatus_DependencyFailed -- ^ Build dependency failed to build
| BuildStatus_LogLimitExceeded
| BuildStatus_NotDeterministic
| BuildStatus_ResolvesToAlreadyValid
Expand All @@ -41,24 +47,27 @@ data BuildStatus =

-- | Result of the build
data BuildResult = BuildResult
{ -- | build status, MiscFailure should be default
status :: !BuildStatus
, -- | possible build error message
errorMessage :: !(Maybe Text)
, -- | How many times this build was performed
timesBuilt :: !Int
, -- | If timesBuilt > 1, whether some builds did not produce the same result
isNonDeterministic :: !Bool
, -- Start time of this build
startTime :: !UTCTime
, -- Stop time of this build
stopTime :: !UTCTime
{ buildResultStatus :: BuildStatus
-- ^ Build status, MiscFailure should be the default
, buildResultErrorMessage :: Maybe Text
-- ^ Possible build error message
, buildResultTimesBuilt :: Maybe Int
-- ^ How many times this build was performed (since 1.29)
, buildResultIsNonDeterministic :: Maybe Bool
-- ^ If timesBuilt > 1, whether some builds did not produce the same result (since 1.29)
, buildResultStartTime :: Maybe UTCTime
-- ^ Start time of this build (since 1.29)
, buildResultStopTime :: Maybe UTCTime
-- ^ Stop time of this build (since 1.29)
, buildResultBuiltOutputs :: Maybe (Map (DerivationOutput OutputName) Realisation)
-- ^ Mapping of the output names to @Realisation@s (since 1.28)
-- (paths with additional info and their dependencies)
}
deriving (Eq, Generic, Ord, Show)

buildSuccess :: BuildResult -> Bool
buildSuccess BuildResult {..} =
status `elem`
buildSuccess :: BuildStatus -> Bool
buildSuccess x =
x `elem`
[ BuildStatus_Built
, BuildStatus_Substituted
, BuildStatus_AlreadyValid
Expand Down
67 changes: 48 additions & 19 deletions hnix-store-core/src/System/Nix/DerivedPath.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,22 @@ module System.Nix.DerivedPath (
, derivedPathToText
) where

import Data.Bifunctor (first)
import GHC.Generics (Generic)
import Data.Set (Set)
import Data.Text (Text)
import System.Nix.StorePath (StoreDir, StorePath, StorePathName, InvalidPathError)
import System.Nix.OutputName (OutputName, InvalidNameError)
import System.Nix.StorePath (StoreDir(..), StorePath, InvalidPathError)

import qualified Data.Bifunctor
import qualified Data.ByteString.Char8
import qualified Data.Set
import qualified Data.Text
import qualified System.Nix.OutputName
import qualified System.Nix.StorePath

data OutputsSpec =
OutputsSpec_All
| OutputsSpec_Names (Set StorePathName)
| OutputsSpec_Names (Set OutputName)
deriving (Eq, Generic, Ord, Show)

data DerivedPath =
Expand All @@ -32,20 +35,20 @@ data DerivedPath =

data ParseOutputsError =
ParseOutputsError_InvalidPath InvalidPathError
| ParseOutputsError_InvalidName InvalidNameError
| ParseOutputsError_NoNames
| ParseOutputsError_NoPrefix StoreDir Text
deriving (Eq, Ord, Show)

convertError
:: Either InvalidPathError a
-> Either ParseOutputsError a
convertError = first ParseOutputsError_InvalidPath

parseOutputsSpec :: Text -> Either ParseOutputsError OutputsSpec
parseOutputsSpec t
| t == "*" = Right OutputsSpec_All
| otherwise = do
names <- mapM
(convertError . System.Nix.StorePath.makeStorePathName)
( Data.Bifunctor.first
ParseOutputsError_InvalidName
. System.Nix.OutputName.mkOutputName
)
(Data.Text.splitOn "," t)
if null names
then Left ParseOutputsError_NoNames
Expand All @@ -55,21 +58,47 @@ outputsSpecToText :: OutputsSpec -> Text
outputsSpecToText = \case
OutputsSpec_All -> "*"
OutputsSpec_Names ns ->
Data.Text.intercalate "," (fmap System.Nix.StorePath.unStorePathName (Data.Set.toList ns))
Data.Text.intercalate
","
(fmap System.Nix.OutputName.unOutputName
(Data.Set.toList ns)
)

parseDerivedPath
:: StoreDir
-> Text
-> Either ParseOutputsError DerivedPath
parseDerivedPath root p =
case Data.Text.breakOn "!" p of
(s, r) ->
if Data.Text.null r
then DerivedPath_Opaque
<$> (convertError $ System.Nix.StorePath.parsePathFromText root s)
else DerivedPath_Built
<$> (convertError $ System.Nix.StorePath.parsePathFromText root s)
<*> parseOutputsSpec (Data.Text.drop (Data.Text.length "!") r)
parseDerivedPath root@(StoreDir sd) path =
let -- We need to do a bit more legwork for case
-- when StoreDir contains '!'
-- which is generated by its Arbitrary instance
textRoot = Data.Text.pack
$ Data.ByteString.Char8.unpack sd

in case Data.Text.stripPrefix textRoot path of
Nothing -> Left $ ParseOutputsError_NoPrefix root path
Just woRoot ->
case Data.Text.breakOn "!" woRoot of
(pathNoPrefix, r) ->
if Data.Text.null r
then DerivedPath_Opaque
<$> (convertError
$ System.Nix.StorePath.parsePathFromText
root
path
)
else DerivedPath_Built
<$> (convertError
$ System.Nix.StorePath.parsePathFromText
root
(textRoot <> pathNoPrefix)
)
<*> parseOutputsSpec (Data.Text.drop (Data.Text.length "!") r)
where
convertError
:: Either InvalidPathError a
-> Either ParseOutputsError a
convertError = Data.Bifunctor.first ParseOutputsError_InvalidPath

derivedPathToText :: StoreDir -> DerivedPath -> Text
derivedPathToText root = \case
Expand Down
9 changes: 7 additions & 2 deletions hnix-store-core/src/System/Nix/Fingerprint.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@ import qualified Data.Text as Text
-- | Produce the message signed by a NAR signature
metadataFingerprint :: StoreDir -> StorePath -> Metadata StorePath -> Text
metadataFingerprint storeDir storePath Metadata{..} = let
narSize = fromMaybe 0 narBytes
in fingerprint storeDir storePath narHash narSize (HashSet.toList references)
narSize = fromMaybe 0 metadataNarBytes
in fingerprint
storeDir
storePath
metadataNarHash
narSize
(HashSet.toList metadataReferences)

-- | Produce the message signed by a NAR signature
fingerprint :: StoreDir
Expand Down
29 changes: 29 additions & 0 deletions hnix-store-core/src/System/Nix/OutputName.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{-# LANGUAGE DeriveAnyClass #-}
{-|
Description : Derived path output names
-}

module System.Nix.OutputName
( OutputName(..)
, mkOutputName
-- * Re-exports
, System.Nix.StorePath.InvalidNameError(..)
, System.Nix.StorePath.parseNameText
) where

import Data.Hashable (Hashable)
import Data.Text (Text)
import GHC.Generics (Generic)
import System.Nix.StorePath (InvalidNameError)

import qualified System.Nix.StorePath

-- | Name of the derived path output
-- Typically used for "dev", "doc" sub-outputs
newtype OutputName = OutputName
{ -- | Extract the contents of the name.
unOutputName :: Text
} deriving (Eq, Generic, Hashable, Ord, Show)

mkOutputName :: Text -> Either InvalidNameError OutputName
mkOutputName = fmap OutputName . System.Nix.StorePath.parseNameText
Loading