@@ -33,6 +33,14 @@ module System.Nix.Store.Remote.Serializer
33
33
, protoVersion
34
34
-- * StorePath
35
35
, storePath
36
+ , storePathHashPart
37
+ , storePathName
38
+ -- * Metadata
39
+ , pathMetadata
40
+ -- * Some HashAlgo
41
+ , someHashAlgo
42
+ -- * Digest
43
+ , digest
36
44
-- * Derivation
37
45
, derivation
38
46
-- * Derivation
@@ -59,12 +67,15 @@ import Control.Monad.Reader (MonadReader)
59
67
import Control.Monad.Trans (MonadTrans , lift )
60
68
import Control.Monad.Trans.Reader (ReaderT , runReaderT )
61
69
import Control.Monad.Trans.Except (ExceptT , runExceptT )
70
+ import Crypto.Hash (Digest , HashAlgorithm , SHA256 )
62
71
import Data.ByteString (ByteString )
72
+ import Data.Dependent.Sum (DSum ((:=>) ))
63
73
import Data.Fixed (Uni )
64
74
import Data.Hashable (Hashable )
65
75
import Data.HashSet (HashSet )
66
76
import Data.Map (Map )
67
77
import Data.Set (Set )
78
+ import Data.Some (Some )
68
79
import Data.Text (Text )
69
80
import Data.Time (NominalDiffTime , UTCTime )
70
81
import Data.Vector (Vector )
@@ -86,13 +97,23 @@ import qualified Data.Time.Clock.POSIX
86
97
import qualified Data.Vector
87
98
88
99
import Data.Serializer
100
+ import System.Nix.Base (BaseEncoding (NixBase32 ))
89
101
import System.Nix.Build (BuildMode , BuildResult (.. ))
102
+ import System.Nix.ContentAddress (ContentAddress )
90
103
import System.Nix.Derivation (Derivation (.. ), DerivationOutput (.. ))
91
104
import System.Nix.DerivedPath (DerivedPath , ParseOutputsError )
92
- import System.Nix.StorePath (HasStoreDir (.. ), InvalidPathError , StorePath )
105
+ import System.Nix.Hash (HashAlgo )
106
+ import System.Nix.StorePath (HasStoreDir (.. ), InvalidPathError , StorePath , StorePathHashPart , StorePathName )
107
+ import System.Nix.StorePath.Metadata (Metadata (.. ), StorePathTrust (.. ))
93
108
import System.Nix.Store.Remote.Types
94
109
110
+ import qualified Data.Coerce
111
+ import qualified Data.Bifunctor
112
+ import qualified Data.Some
113
+ import qualified System.Nix.Base
114
+ import qualified System.Nix.ContentAddress
95
115
import qualified System.Nix.DerivedPath
116
+ import qualified System.Nix.Hash
96
117
import qualified System.Nix.StorePath
97
118
98
119
-- | Transformer for @Serializer@
@@ -144,10 +165,15 @@ data PrimError
144
165
, badPaddingLen :: Int
145
166
, badPaddingPads :: [Word8 ]
146
167
}
168
+ | PrimError_ContentAddress String
147
169
| PrimError_DerivedPath ParseOutputsError
170
+ | PrimError_Digest String
148
171
| PrimError_EnumOutOfMinBound Int
149
172
| PrimError_EnumOutOfMaxBound Int
173
+ | PrimError_HashAlgo String
150
174
| PrimError_IllegalBool Word64
175
+ | PrimError_InvalidNixBase32
176
+ | PrimError_NarHashMustBeSHA256
151
177
| PrimError_NotYetImplemented String (ForPV ProtoVersion )
152
178
| PrimError_Path InvalidPathError
153
179
deriving (Eq , Ord , Generic , Show )
@@ -260,7 +286,7 @@ maybeText = mapIsoSerializer
260
286
t | Data.Text. null t -> Nothing
261
287
t | otherwise -> Just t
262
288
)
263
- (Prelude. maybe mempty id )
289
+ (maybe mempty id )
264
290
text
265
291
266
292
-- * UTCTime
@@ -379,6 +405,140 @@ storePath = Serializer
379
405
$ System.Nix.StorePath. storePathToRawFilePath sd p
380
406
}
381
407
408
+ storePathHashPart :: NixSerializer r PrimError StorePathHashPart
409
+ storePathHashPart =
410
+ mapIsoSerializer
411
+ System.Nix.StorePath. unsafeMakeStorePathHashPart
412
+ System.Nix.StorePath. unStorePathHashPart
413
+ $ mapPrismSerializer
414
+ (Data.Bifunctor. first (pure PrimError_InvalidNixBase32 )
415
+ . System.Nix.Base. decodeWith NixBase32 )
416
+ (System.Nix.Base. encodeWith NixBase32 )
417
+ text
418
+
419
+ storePathName :: NixSerializer r PrimError StorePathName
420
+ storePathName =
421
+ mapPrismSerializer
422
+ (Data.Bifunctor. first PrimError_Path
423
+ . System.Nix.StorePath. makeStorePathName)
424
+ System.Nix.StorePath. unStorePathName
425
+ text
426
+
427
+ pathMetadata
428
+ :: HasStoreDir r
429
+ => NixSerializer r PrimError (Metadata StorePath )
430
+ pathMetadata = Serializer
431
+ { getS = do
432
+ deriverPath <- getS maybePath
433
+
434
+ digest' <- getS $ digest NixBase32
435
+ let narHash = System.Nix.Hash. HashAlgo_SHA256 :=> digest'
436
+
437
+ references <- getS $ hashSet storePath
438
+ registrationTime <- getS time
439
+ narBytes <- (\ case
440
+ 0 -> Nothing
441
+ size -> Just size) <$> getS int
442
+ trust <- getS storePathTrust
443
+
444
+ _sigStrings <- getS $ list text
445
+ contentAddress <- getS maybeContentAddress
446
+
447
+ let
448
+ -- XXX: signatures need pubkey from config
449
+ sigs = mempty
450
+ pure $ Metadata {.. }
451
+
452
+ , putS = \ Metadata {.. } -> do
453
+ putS maybePath deriverPath
454
+
455
+ let putNarHash
456
+ :: DSum HashAlgo Digest
457
+ -> SerialT r PrimError PutM ()
458
+ putNarHash = \ case
459
+ System.Nix.Hash. HashAlgo_SHA256 :=> d
460
+ -> putS (digest @ SHA256 NixBase32 ) d
461
+ _ -> throwError PrimError_NarHashMustBeSHA256
462
+
463
+ putNarHash narHash
464
+
465
+ putS (hashSet storePath) references
466
+ putS time registrationTime
467
+ putS int $ Prelude. maybe 0 id $ narBytes
468
+ putS storePathTrust trust
469
+ putS (hashSet text) mempty
470
+ putS maybeContentAddress contentAddress
471
+ }
472
+ where
473
+ maybeContentAddress
474
+ :: NixSerializer r PrimError (Maybe ContentAddress )
475
+ maybeContentAddress =
476
+ mapPrismSerializer
477
+ (maybe
478
+ (pure Nothing )
479
+ $ Data.Bifunctor. bimap
480
+ PrimError_ContentAddress
481
+ Just
482
+ . System.Nix.ContentAddress. parseContentAddress
483
+ )
484
+ (fmap System.Nix.ContentAddress. buildContentAddress)
485
+ maybeText
486
+
487
+ maybePath
488
+ :: HasStoreDir r
489
+ => NixSerializer r PrimError (Maybe StorePath )
490
+ maybePath = Serializer
491
+ { getS = do
492
+ getS maybeText >>= \ case
493
+ Nothing -> pure Nothing
494
+ Just t -> do
495
+ sd <- Control.Monad.Reader. asks hasStoreDir
496
+ either
497
+ (throwError . PrimError_Path )
498
+ (pure . pure )
499
+ $ System.Nix.StorePath. parsePathFromText sd t
500
+
501
+ , putS = \ case
502
+ Nothing -> putS maybeText Nothing
503
+ Just p -> do
504
+ sd <- Control.Monad.Reader. asks hasStoreDir
505
+ putS text $ System.Nix.StorePath. storePathToText sd p
506
+ }
507
+
508
+ storePathTrust =
509
+ mapIsoSerializer
510
+ (\ case False -> BuiltElsewhere ; True -> BuiltLocally )
511
+ (\ case BuiltElsewhere -> False ; BuiltLocally -> True )
512
+ bool
513
+
514
+
515
+ -- * Some HashAlgo
516
+
517
+ someHashAlgo :: NixSerializer r PrimError (Some HashAlgo )
518
+ someHashAlgo =
519
+ mapPrismSerializer
520
+ (Data.Bifunctor. first PrimError_HashAlgo
521
+ . System.Nix.Hash. textToAlgo)
522
+ (Data.Some. foldSome System.Nix.Hash. algoToText)
523
+ text
524
+
525
+ -- * Digest
526
+
527
+ digest
528
+ :: forall a r
529
+ . HashAlgorithm a
530
+ => BaseEncoding
531
+ -> NixSerializer r PrimError (Digest a )
532
+ digest base =
533
+ mapIsoSerializer
534
+ Data.Coerce. coerce
535
+ Data.Coerce. coerce
536
+ $ mapPrismSerializer
537
+ (Data.Bifunctor. first PrimError_Digest
538
+ . System.Nix.Hash. decodeDigestWith @ a base)
539
+ (System.Nix.Hash. encodeDigestWith base)
540
+ $ text
541
+
382
542
derivationOutput
383
543
:: HasStoreDir r
384
544
=> NixSerializer r PrimError (DerivationOutput StorePath Text )
0 commit comments