about summary refs log tree commit diff
path: root/third_party/nix/src/libstore
diff options
context:
space:
mode:
authorGriffin Smith <grfn@gws.fyi>2020-08-04T03·50-0400
committerglittershark <grfn@gws.fyi>2020-08-05T03·24+0000
commit28c7e926ea48e4f5e57b9b8d1a70ccc494b2c188 (patch)
treeeb45441b3550fcd097d872dd23c0d87c8209e13a /third_party/nix/src/libstore
parentb15b447fcb25fc6232a61cbe5c869fa473c12efc (diff)
feat(3p/nix): Implement AddToStore rpc client r/1594
Implement the AddToStore RPC client method, which uses an
AddToStorePathWriterSink (the dual of the AddToStorePathReaderSource on
the server side) to hook into the dumpPath machinery (which we should
refactor not to use sinks or sources, but not yet) and write dumped
paths as binary data over gRPC. With this commit and sandboxing
disabled, the following derivation builds cleanly:

    derivation {
      name = "test";
      builder = ./build.sh;
      system = "x86_64-linux";
    }

where build.sh has chmod +x and contains:

    #!/bin/sh
    echo 1 > $out

Change-Id: I94cab86f0825a3a9993262a9807130645c13bf44
Reviewed-on: https://cl.tvl.fyi/c/depot/+/1638
Reviewed-by: kanepyork <rikingcoding@gmail.com>
Tested-by: BuildkiteCI
Diffstat (limited to 'third_party/nix/src/libstore')
-rw-r--r--third_party/nix/src/libstore/rpc-store.cc52
1 files changed, 51 insertions, 1 deletions
diff --git a/third_party/nix/src/libstore/rpc-store.cc b/third_party/nix/src/libstore/rpc-store.cc
index f0abdd42efa9..0b57127610ad 100644
--- a/third_party/nix/src/libstore/rpc-store.cc
+++ b/third_party/nix/src/libstore/rpc-store.cc
@@ -1,6 +1,7 @@
 #include "rpc-store.hh"
 
 #include <algorithm>
+#include <filesystem>
 #include <memory>
 
 #include <absl/status/status.h>
@@ -20,6 +21,7 @@
 #include "libproto/worker.grpc.pb.h"
 #include "libproto/worker.pb.h"
 #include "libstore/store-api.hh"
+#include "libutil/archive.hh"
 #include "libutil/hash.hh"
 #include "libutil/types.hh"
 
@@ -54,6 +56,32 @@ T FillFrom(const U& src) {
   return result;
 }
 
+class AddToStorePathWriterSink : public BufferedSink {
+ public:
+  explicit AddToStorePathWriterSink(
+      std::unique_ptr<
+          grpc_impl::ClientWriter<class nix::proto::AddToStoreRequest>>&&
+          writer)
+      : writer_(std::move(writer)), good_(true) {}
+
+  bool good() override { return good_; }
+
+  void write(const unsigned char* data, size_t len) override {
+    proto::AddToStoreRequest req;
+    req.set_data(data, len);
+    if (!writer_->Write(req)) {
+      good_ = false;
+    }
+  }
+
+  grpc::Status Finish() { return writer_->Finish(); }
+
+ private:
+  std::unique_ptr<grpc_impl::ClientWriter<class nix::proto::AddToStoreRequest>>
+      writer_;
+  bool good_;
+};
+
 constexpr absl::StatusCode GRPCStatusCodeToAbsl(grpc::StatusCode code) {
   switch (code) {
     case grpc::StatusCode::OK:
@@ -304,7 +332,29 @@ void RpcStore::addToStore(const ValidPathInfo& info,
 Path RpcStore::addToStore(const std::string& name, const Path& srcPath,
                           bool recursive, HashType hashAlgo, PathFilter& filter,
                           RepairFlag repair) {
-  throw Unsupported(absl::StrCat("Not implemented ", __func__));
+  if (repair != 0u) {
+    throw Error(
+        "repairing is not supported when building through the Nix daemon");
+  }
+
+  ClientContext ctx;
+  proto::StorePath response;
+  auto writer = stub_->AddToStore(&ctx, &response);
+
+  proto::AddToStoreRequest metadata_req;
+  metadata_req.mutable_meta()->set_base_name(name);
+  // TODO(grfn): what is fixed?
+  metadata_req.mutable_meta()->set_fixed(!(hashAlgo == htSHA256 && recursive));
+  metadata_req.mutable_meta()->set_recursive(recursive);
+  metadata_req.mutable_meta()->set_hash_type(HashTypeToProto(hashAlgo));
+  writer->Write(metadata_req);
+
+  AddToStorePathWriterSink sink(std::move(writer));
+  dumpPath(std::filesystem::absolute(srcPath), sink);
+  sink.flush();
+  SuccessOrThrow(sink.Finish());
+
+  return response.path();
 }
 
 Path RpcStore::addTextToStore(const std::string& name,