about summary refs log tree commit diff
path: root/third_party/nix/src/libstore/rpc-store.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/nix/src/libstore/rpc-store.cc')
-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,