packages feed

cachix 0.3.6 → 0.3.7

raw patch · 8 files changed

+117/−48 lines, 8 files

Files

CHANGELOG.md view
@@ -7,7 +7,36 @@  ## Unreleased +## [0.3.7] - 2020-03-12++### Added++- Allow specifying number of parallel jobs when pushing: cachix push mycache -j8++### Changed++- Print stderr during streaming of nars    ++### Fixed++- Use max up to 8 cores to prevent performance issues+  on machines with lots of cores++- Get deriver and references from C++ structures rather+  then shelling out (slight performance improvement)++- #251: Assert nar hash before creating narinfo+    +  Fixes rare but annoying bug of "bad nar archive" from Nix.+  Never managed to reproduce. One theory is that the path disappears as+  its deleted by GC or nix-store --delete.++- Print correct path when passing --nixos-folder and encountering an error++ ## [0.3.6] - 2020-02-22++### Fixed  - #275: support LTS-13.x and GHC 8.2.2 
cachix.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.2 name:               cachix-version: 0.3.6+version: 0.3.7 license:            Apache-2.0 license-file:       LICENSE copyright:          2018 Domen Kožar@@ -126,7 +126,7 @@   import:             defaults   main-is:            Main.hs   build-tool-depends: hspec-discover:hspec-discover -any-  ghc-options:        -threaded -rtsopts -with-rtsopts=-N+  ghc-options:        -threaded -rtsopts -with-rtsopts=-maxN8   hs-source-dirs:     cachix   other-modules:      Paths_cachix   autogen-modules:    Paths_cachix
src/Cachix/Client/Commands.hs view
@@ -168,7 +168,7 @@   store <- wait (storeAsync env)   void $     pushClosure-      (mapConcurrentlyBounded 4)+      (mapConcurrentlyBounded (numJobs opts))       (clientenv env)       store       PushCache
src/Cachix/Client/Exception.hs view
@@ -12,6 +12,7 @@   | NoConfig Text   | NetRcParseError Text   | NarStreamingError ExitCode Text+  | NarHashMismatch Text   | DeprecatedCommand Text   | AccessDeniedBinaryCache Text   | BinaryCacheNotFound Text
src/Cachix/Client/InstallationMode.hs view
@@ -100,10 +100,10 @@ nixosBinaryCache maybeConfig bc UseOptions {useNixOSFolder = baseDirectory} = do   eitherPermissions <- try $ getPermissions (toS baseDirectory) :: IO (Either SomeException Permissions)   case eitherPermissions of-    Left _ -> throwIO $ NixOSInstructions noEtcPermissionInstructions+    Left _ -> throwIO $ NixOSInstructions $ noEtcPermissionInstructions $ toS baseDirectory     Right permissions       | writable permissions -> installFiles-      | otherwise -> throwIO $ NixOSInstructions noEtcPermissionInstructions+      | otherwise -> throwIO $ NixOSInstructions $ noEtcPermissionInstructions $ toS baseDirectory   where     installFiles = do       createDirectoryIfMissing True $ toS toplevel@@ -121,10 +121,10 @@     glueModuleFile = toplevel <> ".nix"     cacheModuleFile :: Text     cacheModuleFile = toplevel <> "/" <> toS (name bc) <> ".nix"-    noEtcPermissionInstructions :: Text-    noEtcPermissionInstructions =+    noEtcPermissionInstructions :: Text -> Text+    noEtcPermissionInstructions dir =       [iTrim|-Could not install NixOS configuration to /etc/nixos/ due to lack of write permissions.+Could not install NixOS configuration to ${dir} due to lack of write permissions.  Pass `--nixos-folder /etc/mynixos/` as an alternative location with write permissions.       |]
src/Cachix/Client/OptionsParser.hs view
@@ -77,7 +77,8 @@  data PushOptions   = PushOptions-      { compressionLevel :: Int+      { compressionLevel :: Int,+        numJobs :: Int       }   deriving (Show) @@ -102,12 +103,21 @@         <$> option           (auto >>= validatedLevel)           ( long "compression-level"+              <> short 'c'               <> metavar "[0..9]"               <> help                 "The compression level for XZ compression.\                 \ Take compressor *and* decompressor memory usage into account before using [7..9]!"               <> showDefault               <> value 2+          )+        <*> option+          auto+          ( long "jobs"+              <> short 'j'+              <> help "Number of threads used for pushing store paths."+              <> showDefault+              <> value 4           )     push = (\opts cache f -> Push $ f opts cache) <$> pushOptions <*> nameArg <*> (pushPaths <|> pushWatchStore)     pushPaths =
src/Cachix/Client/Push.hs view
@@ -29,7 +29,6 @@ import Control.Concurrent.Async (mapConcurrently) import qualified Control.Concurrent.QSem as QSem import Control.Exception.Safe (MonadMask, throwM)-import Control.Monad ((>=>)) import Control.Monad.Trans.Resource (ResourceT) import Control.Retry (RetryPolicy, RetryStatus, constantDelay, limitRetries, recoverAll) import Crypto.Sign.Ed25519@@ -48,7 +47,6 @@ import Servant.Client.Streaming hiding (ClientError) import Servant.Conduit () import qualified System.Nix.Base32-import System.Process (readProcess)  data PushCache   = PushCache@@ -133,8 +131,7 @@       storePathSize :: Int64       storePathSize = Store.validPathInfoNarSize pathinfo   onAttempt cb retrystatus storePathSize-  -- TODO: print process stderr?-  (ClosedStream, (stdoutStream, closeStdout), ClosedStream, cph) <- liftIO $ streamingProcess cmd+  (ClosedStream, stdoutStream, Inherited, cph) <- liftIO $ streamingProcess cmd   withXzipCompressor cb $ \xzCompressor -> do     let stream' =           stdoutStream@@ -158,43 +155,43 @@           (Api.createNar (cachixBCStreamingClient name) stream')         $ escalate           >=> \NoContent -> do-            closeStdout             exitcode <- waitForStreamingProcess cph             when (exitcode /= ExitSuccess) $ throwM $ NarStreamingError exitcode $ show cmd-            -- TODO: we're done, so we can leave withClientM. Doing so-            --       will allow more concurrent requests when the number-            --       of XZ compressors is limited-            narSize <- readIORef narSizeRef-            narHash <- ("sha256:" <>) . System.Nix.Base32.encode <$> readIORef narHashRef-            fileHash <- readIORef fileHashRef-            fileSize <- readIORef fileSizeRef-            deriverRaw <- T.strip . toS <$> readProcess "nix-store" ["-q", "--deriver", toS storePath] mempty-            let deriver =-                  if deriverRaw == "unknown-deriver"-                    then deriverRaw-                    else T.drop 11 deriverRaw-            references <- sort . T.lines . T.strip . toS <$> readProcess "nix-store" ["-q", "--references", toS storePath] mempty-            let fp = fingerprint storePath narHash narSize references-                sig = dsign (signingSecretKey $ pushCacheSigningKey cache) fp-                nic =-                  Api.NarInfoCreate-                    { Api.cStoreHash = storeHash,-                      Api.cStoreSuffix = storeSuffix,-                      Api.cNarHash = narHash,-                      Api.cNarSize = narSize,-                      Api.cFileSize = fileSize,-                      Api.cFileHash = toS fileHash,-                      Api.cReferences = fmap (T.drop 11) references,-                      Api.cDeriver = deriver,-                      Api.cSig = toS $ B64.encode $ unSignature sig-                    }-            escalate $ Api.isNarInfoCreateValid nic-            -- Upload narinfo with signature-            escalate <=< (`runClientM` clientEnv) $-              Api.createNarinfo-                (cachixBCClient name)-                (Api.NarInfoC storeHash)-                nic+            return NoContent+    (_ :: NoContent) <- liftIO $ do+      narSize <- readIORef narSizeRef+      narHash <- ("sha256:" <>) . System.Nix.Base32.encode <$> readIORef narHashRef+      narHashNix <- Store.validPathInfoNarHash pathinfo+      when (narHash /= toS narHashNix) $ throwM $ NarHashMismatch "Nar hash mismatch between nix-store --dump and nix db"+      fileHash <- readIORef fileHashRef+      fileSize <- readIORef fileSizeRef+      deriver <- toS <$> Store.validPathInfoDeriver pathinfo+      referencesPathSet <- Store.validPathInfoReferences pathinfo+      references <- sort <$> Store.traversePathSet (pure . toS) referencesPathSet+      let fp = fingerprint storePath narHash narSize references+          sig = dsign (signingSecretKey $ pushCacheSigningKey cache) fp+          nic =+            Api.NarInfoCreate+              { Api.cStoreHash = storeHash,+                Api.cStoreSuffix = storeSuffix,+                Api.cNarHash = narHash,+                Api.cNarSize = narSize,+                Api.cFileSize = fileSize,+                Api.cFileHash = toS fileHash,+                Api.cReferences = fmap (T.drop 11) references,+                Api.cDeriver =+                  if deriver == "unknown-deriver"+                    then deriver+                    else T.drop 11 deriver,+                Api.cSig = toS $ B64.encode $ unSignature sig+              }+      escalate $ Api.isNarInfoCreateValid nic+      -- Upload narinfo with signature+      escalate <=< (`runClientM` clientEnv) $+        Api.createNarinfo+          (cachixBCClient name)+          (Api.NarInfoC storeHash)+          nic     onDone cb  -- Catches all exceptions except skipAsyncExceptions
src/Cachix/Client/Store.hs view
@@ -13,6 +13,9 @@     followLinksToStorePath,     queryPathInfo,     validPathInfoNarSize,+    validPathInfoNarHash,+    validPathInfoDeriver,+    validPathInfoReferences,      -- * Get closures     computeFSClosure,@@ -121,6 +124,35 @@       [C.pure| long         { (*$fptr-ptr:(refValidPathInfo* vpi))->narSize }       |]++-- | Copy the narHash field of a ValidPathInfo struct. Source: store-api.hh+validPathInfoNarHash :: ForeignPtr (Ref ValidPathInfo) -> IO ByteString+validPathInfoNarHash vpi =+  unsafePackMallocCString+    =<< [C.exp| const char+        *{ strdup((*$fptr-ptr:(refValidPathInfo* vpi))->narHash.to_string().c_str()) }+      |]++-- | Deriver field of a ValidPathInfo struct. Source: store-api.hh+validPathInfoDeriver :: ForeignPtr (Ref ValidPathInfo) -> IO ByteString+validPathInfoDeriver vpi =+  unsafePackMallocCString+    =<< [C.throwBlock| const char*+        {+          std::optional<Path> deriver = (*$fptr-ptr:(refValidPathInfo* vpi))->deriver;+          return strdup((deriver == "" ? "unknown-deriver" : deriver->c_str()));+        }+      |]++-- | References field of a ValidPathInfo struct. Source: store-api.hh+validPathInfoReferences :: ForeignPtr (Ref ValidPathInfo) -> IO PathSet+validPathInfoReferences vpi = do+  ptr <-+    [C.exp| const PathSet*+            { new PathSet((*$fptr-ptr:(refValidPathInfo* vpi))->references) }+        |]+  fptr <- newForeignPtr finalizePathSet ptr+  pure $ PathSet fptr  ----- PathSet ----- newtype PathSet = PathSet (ForeignPtr (C.Set C.CxxString))