Skip to content

Commit

Permalink
Merge pull request #44 from numtide/more-config
Browse files Browse the repository at this point in the history
More config
  • Loading branch information
zimbatm authored Jul 28, 2024
2 parents 3d331de + 730ae74 commit a348985
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 86 deletions.
8 changes: 0 additions & 8 deletions .nowignore

This file was deleted.

6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ Inside the provided nix shell run:

This will create a small local server with live reload that emulates now.sh.

Currently, the default port is 8383. You can change it by setting the `PORT` environment variable.
Currently, the default port is 8383. You can change it by setting the `PORT`
environment variable, or `HTTP_ADDR` to also change the bind address.

## Usage

Expand All @@ -33,7 +34,7 @@ the fly. That's it.

E.g.:

* https://nar-serve.zimbatm.now.sh/nix/store/barxv95b8arrlh97s6axj8k7ljn7aky1-go-1.12/share/go/doc/effective_go.html
* https://serve.ntd.one/nix/store/barxv95b8arrlh97s6axj8k7ljn7aky1-go-1.12/share/go/doc/effective_go.html

NAR archives also contain information about the executable bit for each contained file.
nar-serve uses a custom HTTP header named `NAR-executable` to indicate whether the fetched file would be executable.
Expand All @@ -45,6 +46,7 @@ You can use the following environment variables to configure nar-serve:
| Name | Default value | Description |
|:-- |:-- |:-- |
| `PORT` | `8383` | Port number on which nar-service listens |
| `HTTP_ADDR` | `:$PORT` | HTTP address to bind the server to. When set, takes precedence over $PORT. |
| `NAR_CACHE_URL` | `https://cache.nixos.org` | The URL of the Nix store from which NARs are fetched |

## Contributing
Expand Down
104 changes: 28 additions & 76 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,108 +1,51 @@
package main

// this file is being used for local development. It reproduces more
// or less the behaviour of now.sh but all compiled into a single binary.

import (
"embed"
"net/http"
"io"
"os"

unpack "github.com/numtide/nar-serve/api/unpack"
"github.com/urfave/negroni"
)

const robotsTxt = `
User-agent: *
Disallow: /nix/store
`

const indexPage = `
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
<title>nar-serve</title>
<link rel=stylesheet
href="https://cdnjs.cloudflare.com/ajax/libs/Primer/11.0.0/build.css">
</head>
<body>
<div class="container-lg px-3 my-5 markdown-body">
<h1>nar-serve</h1>
<p>All the files in <a href="https://cache.nixos.org">cache.nixos.org</a> are packed in NAR files which makes them not directly accessible. This service allows to dowload, decompress, unpack and serve any file in the cache on the fly.</p>
<h2>Use cases</h2>
<ul>
<li>Avoid publishing build artifacts to both the binary cache and
another service.</li>
<li>Allows to share build results easily.</li>
<li>Inspect the content of a NAR file.</li>
</ul>
<h2>Usage</h2>
<ol>
<li>Pick a full store path in your filesystem.</li>
<li>Paste it in the form below.</li>
<li>Click submit. TADA!</li>
</ol>
<dl class="form-group">
<dt><label for=reformat-input>Store path</label></dt>
<dd>
<input type=text id=store-path class="form-control input-block">
</dd>
</dl>
<button class="btn btn-primary" id=store-path-submit>Load</button>
<h2>Examples</h2>
<ul>
<li><a href="/nix/store/zk5crljigizl5snkfyaijja89bb6228x-rake-12.3.1/bin/rake">readlink -f $(which rake)</a></li>
<li><a href="/nix/store/barxv95b8arrlh97s6axj8k7ljn7aky1-go-1.12/share/go/doc/effective_go.html">/nix/store/barxv95b8arrlh97s6axj8k7ljn7aky1-go-1.12/share/go/doc/effective_go.html</a></li>
</ul>
<hr>
<p>
Like this project? Star it on <a href="https://github.com/numtide/nar-serve">GitHub</a>.
<script>
const storePathEl = document.getElementById("store-path");
const storePathSubmitEl = document.getElementById("store-path-submit");
storePathSubmitEl.onclick = function() {
document.location.pathname = storePathEl.value;
}
</script>
`
//go:embed views/*
var viewsFS embed.FS

func indexHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
w.Write([]byte(indexPage))
f, _ := viewsFS.Open("views/index.html")
_, _ = io.Copy(w, f)
}

func robotsHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(robotsTxt))
f, _ := viewsFS.Open("views/robots.txt")
_, _ = io.Copy(w, f)
f.Close()
}

func healthzHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK"))
_, _ = w.Write([]byte("OK"))
}

func main() {
var (
port = getEnv("PORT", "8383")
addr = getEnv("HTTP_ADDR", "")
)

if addr == "" {
addr = ":" + port
}

mux := http.NewServeMux()
mux.HandleFunc("/", indexHandler)
mux.HandleFunc("/healthz", healthzHandler)
mux.HandleFunc("/robots.txt", robotsHandler)
mux.HandleFunc(unpack.MountPath, unpack.Handler)

addr := ":8383"
if port := os.Getenv("PORT"); port != "" {
addr = ":" + port
}

// Includes some default middlewares
// Serve static files from ./public
n := negroni.New(
Expand All @@ -112,3 +55,12 @@ func main() {
n.UseHandler(mux)
n.Run(addr)
}

func getEnv(name, def string) string {
value := os.Getenv(name)
if value == "" {
return def
}
return value
}

58 changes: 58 additions & 0 deletions views/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
<title>nar-serve</title>
<link rel=stylesheet
href="https://cdnjs.cloudflare.com/ajax/libs/Primer/11.0.0/build.css">
</head>
<body>
<div class="container-lg px-3 my-5 markdown-body">
<h1>nar-serve</h1>

<p>All the files in <a href="https://cache.nixos.org">cache.nixos.org</a> are packed in NAR files which makes them not directly accessible. This service allows to dowload, decompress, unpack and serve any file in the cache on the fly.</p>

<h2>Use cases</h2>

<ul>
<li>Avoid publishing build artifacts to both the binary cache and
another service.</li>
<li>Allows to share build results easily.</li>
<li>Inspect the content of a NAR file.</li>
</ul>

<h2>Usage</h2>
<ol>
<li>Pick a full store path in your filesystem.</li>
<li>Paste it in the form below.</li>
<li>Click submit. TADA!</li>
</ol>

<dl class="form-group">
<dt><label for=reformat-input>Store path</label></dt>
<dd>
<input type=text id=store-path class="form-control input-block">
</dd>
</dl>

<button class="btn btn-primary" id=store-path-submit>Load</button>

<h2>Examples</h2>
<ul>
<li><a href="/nix/store/zk5crljigizl5snkfyaijja89bb6228x-rake-12.3.1/bin/rake">readlink -f $(which rake)</a></li>
<li><a href="/nix/store/barxv95b8arrlh97s6axj8k7ljn7aky1-go-1.12/share/go/doc/effective_go.html">/nix/store/barxv95b8arrlh97s6axj8k7ljn7aky1-go-1.12/share/go/doc/effective_go.html</a></li>
</ul>


<hr>
<p>
Like this project? Star it on <a href="https://github.com/numtide/nar-serve">GitHub</a>.

<script>
const storePathEl = document.getElementById("store-path");
const storePathSubmitEl = document.getElementById("store-path-submit");

storePathSubmitEl.onclick = function() {
document.location.pathname = storePathEl.value;
}
</script>
2 changes: 2 additions & 0 deletions views/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
User-agent: *
Disallow: /nix/store

0 comments on commit a348985

Please sign in to comment.