Add support for /log/ API
This commit is contained in:
parent
3bd298c02a
commit
24fb4b7fea
@ -1,6 +1,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <nix/store-api.hh>
|
#include <nix/store-api.hh>
|
||||||
|
#include <nix/log-store.hh>
|
||||||
#include "nix.hh"
|
#include "nix.hh"
|
||||||
|
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
@ -161,7 +162,8 @@ void signString
|
|||||||
void dumpPath(char const * const hashPart, struct string * const output) {
|
void dumpPath(char const * const hashPart, struct string * const output) {
|
||||||
ref<Store> store = getStore();
|
ref<Store> store = getStore();
|
||||||
|
|
||||||
std::optional<StorePath> storePath= store->queryPathFromHashPart(hashPart);
|
std::optional<StorePath> storePath =
|
||||||
|
store->queryPathFromHashPart(hashPart);
|
||||||
|
|
||||||
if (storePath.has_value()) {
|
if (storePath.has_value()) {
|
||||||
StringSink sink;
|
StringSink sink;
|
||||||
@ -174,4 +176,30 @@ void dumpPath(char const * const hashPart, struct string * const output) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dumpLog(char const * const hashPart, struct string * const output) {
|
||||||
|
ref<Store> store = getStore();
|
||||||
|
|
||||||
|
std::optional<StorePath> storePath =
|
||||||
|
store->queryPathFromHashPart(hashPart);
|
||||||
|
|
||||||
|
if (storePath.has_value()) {
|
||||||
|
auto subs = getDefaultSubstituters();
|
||||||
|
|
||||||
|
subs.push_front(store);
|
||||||
|
|
||||||
|
for (auto & sub : subs) {
|
||||||
|
LogStore * logStore = dynamic_cast<LogStore *>(&*sub);
|
||||||
|
|
||||||
|
std::optional<std::string> log = logStore->getBuildLog(storePath.value());
|
||||||
|
|
||||||
|
if (log.has_value()) {
|
||||||
|
copyString(log.value(), output);
|
||||||
|
} else {
|
||||||
|
*output = emptyString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*output = emptyString;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
36
src/Main.hs
36
src/Main.hs
@ -251,7 +251,7 @@ makeApplication ApplicationOptions{..} request respond = do
|
|||||||
Nothing -> noSuchPath
|
Nothing -> noSuchPath
|
||||||
Just storePath -> return storePath
|
Just storePath -> return storePath
|
||||||
|
|
||||||
PathInfo{ narSize, narHash } <- liftIO (Nix.queryPathInfo storePath)
|
PathInfo{ narHash } <- liftIO (Nix.queryPathInfo storePath)
|
||||||
|
|
||||||
Monad.unless (all (narHash ==) maybeExpectedNarHash) do
|
Monad.unless (all (narHash ==) maybeExpectedNarHash) do
|
||||||
let headers = [ ("Content-Type", "text/plain") ]
|
let headers = [ ("Content-Type", "text/plain") ]
|
||||||
@ -273,21 +273,31 @@ makeApplication ApplicationOptions{..} request respond = do
|
|||||||
Nothing -> noSuchPath
|
Nothing -> noSuchPath
|
||||||
Just bytes -> return bytes
|
Just bytes -> return bytes
|
||||||
|
|
||||||
let contentLength =
|
let lazyBytes = ByteString.Lazy.fromStrict bytes
|
||||||
( ByteString.Lazy.toStrict
|
|
||||||
. Builder.toLazyByteString
|
|
||||||
. Builder.word64Dec
|
|
||||||
) narSize
|
|
||||||
|
|
||||||
let headers =
|
let headers = [ ("Content-Type", "text/plain") ]
|
||||||
[ ("Content-Type", "text/plain")
|
|
||||||
, ("Content-Length", contentLength)
|
|
||||||
]
|
|
||||||
|
|
||||||
let builder = Builder.byteString bytes
|
|
||||||
|
|
||||||
let response =
|
let response =
|
||||||
Wai.responseBuilder Types.status200 headers builder
|
Wai.responseLBS Types.status200 headers lazyBytes
|
||||||
|
|
||||||
|
done response
|
||||||
|
|
||||||
|
| Just suffix <- ByteString.stripPrefix "/log/" rawPath
|
||||||
|
, 32 <= ByteString.length suffix -> do
|
||||||
|
let hashPart = ByteString.take 32 suffix
|
||||||
|
|
||||||
|
maybeBytes <- liftIO (Nix.dumpLog hashPart)
|
||||||
|
|
||||||
|
bytes <- case maybeBytes of
|
||||||
|
Nothing -> noSuchPath
|
||||||
|
Just bytes -> return bytes
|
||||||
|
|
||||||
|
let lazyBytes = ByteString.Lazy.fromStrict bytes
|
||||||
|
|
||||||
|
let headers = [ ("Content-Type", "text/plain") ]
|
||||||
|
|
||||||
|
let response =
|
||||||
|
Wai.responseLBS Types.status200 headers lazyBytes
|
||||||
|
|
||||||
done response
|
done response
|
||||||
|
|
||||||
|
|||||||
15
src/Nix.hsc
15
src/Nix.hsc
@ -275,3 +275,18 @@ dumpPath hashPart = do
|
|||||||
if data_ == Foreign.nullPtr
|
if data_ == Foreign.nullPtr
|
||||||
then return Nothing
|
then return Nothing
|
||||||
else fmap Just (fromString_ string_)
|
else fmap Just (fromString_ string_)
|
||||||
|
|
||||||
|
foreign import ccall "dumpLog" dumpLog_
|
||||||
|
:: CString -> Ptr String_ -> IO ()
|
||||||
|
|
||||||
|
dumpLog :: ByteString -> IO (Maybe ByteString)
|
||||||
|
dumpLog hashPart = do
|
||||||
|
ByteString.useAsCString hashPart \cHashPart -> do
|
||||||
|
Foreign.alloca \output -> do
|
||||||
|
let open = dumpLog_ cHashPart output
|
||||||
|
let close = freeString output
|
||||||
|
Exception.bracket_ open close do
|
||||||
|
string_@String_{ data_} <- peek output
|
||||||
|
if data_ == Foreign.nullPtr
|
||||||
|
then return Nothing
|
||||||
|
else fmap Just (fromString_ string_)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user