Closed soulomoon closed 1 year ago
It seems a lot of name conflict between Effects.hs
and hnix store
I am now able to compute the correct hash and output path using makeFixedOutputPath
.
But I do not understand why using addTextToStore'
returns a output path with different hash.
Evaluating:
--eval -E 'builtins.fetchurl
https://raw.githubusercontent.com/haskell-nix/hnix/master/default.nix'
"/nix/store/f8hrj60i9d6d7699ydmwz6d74mzdiiz7-default.nix"
makeFixedOutputPath
:
/nix/store/f8hrj60i9d6d7699ydmwz6d74mzdiiz7-default.nix
addTextToStore'
yield a different result:
/nix/store/y05dz7dgvigxrpa5qjvj72c9jnrbx65f-default.nix
Some digging, I try to trace addTextToStore'
to hnix store, but it seems it is just proxy to remote store
Considering if it is the padding diff the hash
the remote store line is here https://github.com/NixOS/nix/blob/e34fe47d0ce19fc7657970fb0e610bffbc3e43f0/src/libstore/daemon.cc#L351
It's my mistake, the reason is that the addTextToStore and makefixouput use different hash object for hashing a name:
text:sha256:37268335dd6931045bdcdf92623ff819a64244b53d0e746d438797349d4da578:/nix/store:test
fixed:out:sha256:37268335dd6931045bdcdf92623ff819a64244b53d0e746d438797349d4da578:
-> b2ddea1e93007908327ef4403126f8e9caa57c4c3d19ea11e382a5d18e9ede62
-> output:out:sha256:b2ddea1e93007908327ef4403126f8e9caa57c4c3d19ea11e382a5d18e9ede62:/nix/store:test
where 37268335dd6931045bdcdf92623ff819a64244b53d0e746d438797349d4da578
is hash of the content.
Here is the problem, how do I add the text along with fixed output through hnix store
You can open hnix-store
reports during work.
It is much more malleable, we can shape API there to fit with hnix
.
Also would thank if details as in https://github.com/haskell-nix/hnix/pull/1051#issuecomment-1031380804 would end-up noted in the source code.
You can open
hnix-store
reports during work.It is much more malleable, we can shape API there to fit with
hnix
.Also would thank if details as in #1051 (comment) would end-up noted in the source code.
Sure, I am still getting familiar with the interaction between hnix-store, nix-daemon and hnix.
How nix implement fetchurl
break down into(source) :
makeFixedOutputPath
from hnix-storeaddToStore
api from hnix-store lacking functionality to send string to daemon. haskell-nix/hnix-store#176hnix-store api for addToStore
does seems a bit off comparing to nix, we should shape API as in nix.
baseNameOf :: Text -> Text
baseNameOf a = Text.takeWhileEnd (/='/') $ Text.dropWhileEnd (=='/') a
str :: ByteString -> ByteString
str t =
let
len = B.length t
in
int len <> padBS len t
-- | Distance to the next multiple of 8
padLen :: Int -> Int
padLen n = (8 - n) `mod` 8
padBS :: Int -> ByteString -> ByteString
padBS strSize bs = bs <> B.replicate (padLen strSize) 0
int :: Integral a => a -> ByteString
int n = Serial.runPut $ Serial.putInt64le $ fromIntegral n
-- | dumpString
-- dump a string to nar
dumpString :: ByteString -> NarSource Store.Remote.MonadStore
dumpString text yield = do
yield $ str "nix-archive-1"
yield $ str "("
yield $ str "type"
yield $ str "regular"
yield $ str "contents"
yield $ str text
yield $ str ")"
addToFile :: System.Nix.StorePath.StorePathName -> ByteString -> IO (Either ErrorCall Store.StorePath)
addToFile name content = do
res <- Store.Remote.runStore $ addToStore1 name (dumpString content) False (const True) False
either
Left -- err
pure -- path
<$> parseStoreResult "addToFile" res
type NarSource m = (ByteString -> m ()) -> m ()
-- | Pack `Nar` and add it to the store.
addToStore1
:: Store.StorePathName -- ^ Name part of the newly created `StorePath`
-> NarSource Store.Remote.MonadStore -- ^ provide nar stream
-> Bool -- ^ Add target directory recursively
-> (FilePath -> Bool) -- ^ Path filter function
-> RepairFlag -- ^ Only used by local store backend
-> Store.Remote.MonadStore Store.StorePath
addToStore1 name source recursive _pathFilter _repair = do
Store.runOpArgsIO AddToStore $ \yield -> do
yield $ toStrict $ Data.Binary.Put.runPut $ do
putText $ System.Nix.StorePath.unStorePathName name
putBool $ not $ System.Nix.Hash.algoName @Hash.SHA256 == "sha256" && recursive
putBool recursive
putText $ System.Nix.Hash.algoName @Hash.SHA256
source yield
sockGetPath
-- ** Instances
instance MonadHttp IO where
getURL url =
do
let urlstr = toString url
traceM $ "fetching HTTP URL: " <> urlstr
req <- parseRequest urlstr
manager <-
bool
(newManager defaultManagerSettings)
newTlsManager
(secure req)
response <- httpLbs (req { method = "GET" }) manager
let status = statusCode $ responseStatus response
let body = (B.concat . BL.toChunks) $ responseBody response
let digest::Hash.Digest Hash.SHA256 = Hash.hash body
let name = baseNameOf url
bool
(pure $ Left $ ErrorCall $ "fail, got " <> show status <> " when fetching url = " <> urlstr)
(either (\ err -> pure $ Left $ ErrorCall $ "name: '" <> toString name <> "' is not a valid path name: " <> err)
(\x -> do
res <- addToFile (System.Nix.StorePath.StorePathName name) body
either print print res
print $ Store.makeFixedOutputPath "/nix/store" False digest x
pure $ Right. toStorePath . Store.makeFixedOutputPath "/nix/store" False digest $ x)
(Store.makeStorePathName name))
(status == 200)
hand revising the hnix store addToStore
api is working. But it should be put to hnix-store
I have open a draft to shape the api haskell-nix/hnix-store#177.
The work should continue after haskell-nix/hnix-store#177 is merged or haskell-nix/hnix-store#176 is solved.
Now the builtins.fetchurl would be done Also I unmask the test files It might close #258 as real implementation related #1034