about summary refs log tree commit diff
path: root/tvix/nar-bridge/pkg/server/narinfo_get.go
diff options
context:
space:
mode:
authorFlorian Klink <flokli@flokli.de>2023-10-03T11·49+0300
committerflokli <flokli@flokli.de>2023-10-05T06·17+0000
commit28d1b9c01d009424eed276f5689430897afd97ec (patch)
tree529a924d5ca585db419cff4d5f9e64824fa8416b /tvix/nar-bridge/pkg/server/narinfo_get.go
parent0353108e99c6c2b7f15ea0c99a8ca4fd899d241a (diff)
refactor(tvix/nar-bridge): move pkg/server to pkg/http r/6700
This is only dealing with the HTTP interface.

Change-Id: I011b624fd9f11ea96231b92fea1166c118a219f2
Reviewed-on: https://cl.tvl.fyi/c/depot/+/9535
Tested-by: BuildkiteCI
Autosubmit: flokli <flokli@flokli.de>
Reviewed-by: Connor Brewster <cbrewster@hey.com>
Diffstat (limited to 'tvix/nar-bridge/pkg/server/narinfo_get.go')
-rw-r--r--tvix/nar-bridge/pkg/server/narinfo_get.go147
1 files changed, 0 insertions, 147 deletions
diff --git a/tvix/nar-bridge/pkg/server/narinfo_get.go b/tvix/nar-bridge/pkg/server/narinfo_get.go
deleted file mode 100644
index f2276400c61a..000000000000
--- a/tvix/nar-bridge/pkg/server/narinfo_get.go
+++ /dev/null
@@ -1,147 +0,0 @@
-package server
-
-import (
-	"context"
-	"encoding/base64"
-	"errors"
-	"fmt"
-	"io"
-	"io/fs"
-	"net/http"
-	"path"
-	"strings"
-	"sync"
-
-	castorev1pb "code.tvl.fyi/tvix/castore/protos"
-	storev1pb "code.tvl.fyi/tvix/store/protos"
-	"github.com/go-chi/chi/v5"
-	nixhash "github.com/nix-community/go-nix/pkg/hash"
-	"github.com/nix-community/go-nix/pkg/narinfo"
-	"github.com/nix-community/go-nix/pkg/narinfo/signature"
-	"github.com/nix-community/go-nix/pkg/nixbase32"
-	"github.com/nix-community/go-nix/pkg/nixpath"
-	log "github.com/sirupsen/logrus"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/status"
-)
-
-// renderNarinfo writes narinfo contents to a passes io.Writer, or a returns a
-// (wrapped) io.ErrNoExist error if something doesn't exist.
-// if headOnly is set to true, only the existence is checked, but no content is
-// actually written.
-func renderNarinfo(
-	ctx context.Context,
-	log *log.Entry,
-	pathInfoServiceClient storev1pb.PathInfoServiceClient,
-	narHashToPathInfoMu *sync.Mutex,
-	narHashToPathInfo map[string]*storev1pb.PathInfo,
-	outputHash []byte,
-	w io.Writer,
-	headOnly bool,
-) error {
-	pathInfo, err := pathInfoServiceClient.Get(ctx, &storev1pb.GetPathInfoRequest{
-		ByWhat: &storev1pb.GetPathInfoRequest_ByOutputHash{
-			ByOutputHash: outputHash,
-		},
-	})
-	if err != nil {
-		st, ok := status.FromError(err)
-		if ok {
-			if st.Code() == codes.NotFound {
-				return fmt.Errorf("output hash %v not found: %w", base64.StdEncoding.EncodeToString(outputHash), fs.ErrNotExist)
-			}
-			return fmt.Errorf("unable to get pathinfo, code %v: %w", st.Code(), err)
-		}
-
-		return fmt.Errorf("unable to get pathinfo: %w", err)
-	}
-
-	narHash, err := nixhash.ParseNixBase32("sha256:" + nixbase32.EncodeToString(pathInfo.GetNarinfo().GetNarSha256()))
-	if err != nil {
-		// TODO: return proper error
-		return fmt.Errorf("No usable NarHash found in PathInfo")
-	}
-
-	// add things to the lookup table, in case the same process didn't handle the NAR hash yet.
-	narHashToPathInfoMu.Lock()
-	narHashToPathInfo[narHash.SRIString()] = pathInfo
-	narHashToPathInfoMu.Unlock()
-
-	if headOnly {
-		return nil
-	}
-
-	// convert the signatures from storev1pb signatures to narinfo signatures
-	narinfoSignatures := make([]signature.Signature, 0)
-	for _, pathInfoSignature := range pathInfo.Narinfo.Signatures {
-		narinfoSignatures = append(narinfoSignatures, signature.Signature{
-			Name: pathInfoSignature.GetName(),
-			Data: pathInfoSignature.GetData(),
-		})
-	}
-
-	// extract the name of the node in the pathInfo structure, which will become the output path
-	var nodeName []byte
-	switch v := (pathInfo.GetNode().GetNode()).(type) {
-	case *castorev1pb.Node_File:
-		nodeName = v.File.GetName()
-	case *castorev1pb.Node_Symlink:
-		nodeName = v.Symlink.GetName()
-	case *castorev1pb.Node_Directory:
-		nodeName = v.Directory.GetName()
-	}
-
-	narInfo := narinfo.NarInfo{
-		StorePath:   path.Join(nixpath.StoreDir, string(nodeName)),
-		URL:         "nar/" + nixbase32.EncodeToString(narHash.Digest()) + ".nar",
-		Compression: "none", // TODO: implement zstd compression
-		NarHash:     narHash,
-		NarSize:     uint64(pathInfo.Narinfo.NarSize),
-		References:  pathInfo.Narinfo.GetReferenceNames(),
-		Signatures:  narinfoSignatures,
-	}
-
-	// render .narinfo from pathInfo
-	_, err = io.Copy(w, strings.NewReader(narInfo.String()))
-	if err != nil {
-		return fmt.Errorf("unable to write narinfo to client: %w", err)
-	}
-
-	return nil
-}
-
-func registerNarinfoGet(s *Server) {
-	// GET $outHash.narinfo looks up the PathInfo from the tvix-store,
-	// and then render a .narinfo file to the client.
-	// It will keep the PathInfo in the lookup map,
-	// so a subsequent GET /nar/ $narhash.nar request can find it.
-	s.handler.Get("/{outputhash:^["+nixbase32.Alphabet+"]{32}}.narinfo", func(w http.ResponseWriter, r *http.Request) {
-		defer r.Body.Close()
-
-		ctx := r.Context()
-		log := log.WithField("outputhash", chi.URLParamFromCtx(ctx, "outputhash"))
-
-		// parse the output hash sent in the request URL
-		outputHash, err := nixbase32.DecodeString(chi.URLParamFromCtx(ctx, "outputhash"))
-		if err != nil {
-			log.WithError(err).Error("unable to decode output hash from url")
-			w.WriteHeader(http.StatusBadRequest)
-			_, err := w.Write([]byte("unable to decode output hash from url"))
-			if err != nil {
-				log.WithError(err).Errorf("unable to write error message to client")
-			}
-
-			return
-		}
-
-		err = renderNarinfo(ctx, log, s.pathInfoServiceClient, &s.narHashToPathInfoMu, s.narHashToPathInfo, outputHash, w, false)
-		if err != nil {
-			if errors.Is(err, fs.ErrNotExist) {
-				w.WriteHeader(http.StatusNotFound)
-			} else {
-				log.WithError(err).Warn("unable to render narinfo")
-				w.WriteHeader(http.StatusInternalServerError)
-			}
-		}
-	})
-}