mirror of
https://github.com/imjasonh/kontain.me
synced 2026-07-08 00:55:14 +00:00
split out random to its own image
This commit is contained in:
parent
719a5559e9
commit
b6b6a55059
8 changed files with 162 additions and 51 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB |
|
|
@ -46,7 +46,6 @@ func main() {
|
|||
info: lg.StandardLogger(logging.Info),
|
||||
error: lg.StandardLogger(logging.Error),
|
||||
})
|
||||
http.Handle("/", http.FileServer(http.Dir("/var/run/ko")))
|
||||
|
||||
log.Println("Starting...")
|
||||
port := os.Getenv("PORT")
|
||||
|
|
|
|||
|
|
@ -12,20 +12,39 @@ a { color: blue; }
|
|||
<p><b>kontain.me</b> serves Docker container images generated on-demand at the
|
||||
time they are requested.</p>
|
||||
|
||||
<p><code>docker pull kontain.me/random:latest</code> serves an image containing
|
||||
<h1><code>random.kontain.me</code></h1>
|
||||
|
||||
<p><code>docker pull random.kontain.me/random:latest</code> serves an image containing
|
||||
random data. By default the image contains one layer containing 10 MB of random
|
||||
bytes. You can request a specific size and shape of random image. For example,
|
||||
<code>kontain.me/random:4x100</code> generates a random image of 4 layers of
|
||||
100 random bytes each.
|
||||
|
||||
<h1><code>kontain.me</code></h1>
|
||||
|
||||
<p><code>docker pull kontain.me/ko/[import path]</code> serves an image
|
||||
containing a Go binary fetched using <code>go get</code> and built into a
|
||||
container image using <a
|
||||
href="https://github.com/google/ko"><code>ko</code></a>. For example,
|
||||
href="https://github.com/google/ko"><code>ko</code></a>.</p>
|
||||
|
||||
<p>For example,
|
||||
<code>docker pull kontain.me/ko/github.com/google/ko/cmd/ko</code> will fetch,
|
||||
build and (eventually) serve a Docker image containing <code>ko</code> itself.
|
||||
<i>Koception!</i></p>
|
||||
|
||||
<h1><code>cnb.kontain.me</code></h1>
|
||||
|
||||
<p><code>docker pull cnb.kontain.me/[ghuser]/[ghrepo]:[revision]</code> serves
|
||||
an image fetched from source on GitHub and built using <a
|
||||
href="https://buildpacks.io">CNCF Buildpacks</a>.</p>
|
||||
|
||||
<p>For example, <code>docker pull
|
||||
cnb.kontain.me/buildpack/sample-java-app:b032838</code> fetches, builds
|
||||
and serves a <a href="https://github.com/buildpack/sample-java-app">sample Java
|
||||
app</a>.</p>
|
||||
|
||||
<h1>Caveats</h1>
|
||||
|
||||
<p>The registry does not accept pushes and does not handle requests for images
|
||||
by digest. This is a silly hack and probably isn't stable. Don't rely on it for
|
||||
anything serious. It could probably do a lot of smart things to be a lot
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -29,7 +27,6 @@ import (
|
|||
"cloud.google.com/go/logging"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/random"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
"github.com/google/ko/pkg/build"
|
||||
"github.com/imjasonh/kontain.me/pkg/run"
|
||||
|
|
@ -77,12 +74,9 @@ func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
// API Version check.
|
||||
w.Header().Set("Docker-Distribution-API-Version", "registry/2.0")
|
||||
return
|
||||
case strings.HasPrefix(path, "random/manifests/"):
|
||||
s.serveRandomManifest(w, r)
|
||||
case strings.HasPrefix(path, "ko/") && strings.Contains(path, "/manifests/"):
|
||||
s.serveKoManifest(w, r)
|
||||
case strings.HasPrefix(path, "random/blobs/"),
|
||||
strings.HasPrefix(path, "ko/") && strings.Contains(path, "/blobs/"):
|
||||
case strings.HasPrefix(path, "ko/") && strings.Contains(path, "/blobs/"):
|
||||
serve.Blob(w, r)
|
||||
default:
|
||||
serve.Error(w, serve.ErrNotFound)
|
||||
|
|
@ -142,30 +136,3 @@ func (s *server) serveKoManifest(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
serve.Manifest(w, img)
|
||||
}
|
||||
|
||||
// Capture up to 99 layers of up to 99.9MB each.
|
||||
var randomTagRE = regexp.MustCompile("([0-9]{1,2})x([0-9]{1,8})")
|
||||
|
||||
// konta.in/random:3x10mb
|
||||
// konta.in/random(:latest) -> 1x10mb
|
||||
func (s *server) serveRandomManifest(w http.ResponseWriter, r *http.Request) {
|
||||
tag := strings.TrimPrefix(r.URL.Path, "/v2/random/manifests/")
|
||||
var num, size int64 = 1, 10000000 // 10MB
|
||||
|
||||
// Captured requested num + size from tag.
|
||||
all := randomTagRE.FindStringSubmatch(tag)
|
||||
if len(all) >= 3 {
|
||||
num, _ = strconv.ParseInt(all[1], 10, 64)
|
||||
size, _ = strconv.ParseInt(all[2], 10, 64)
|
||||
}
|
||||
s.info.Printf("generating random image with %d layers of %d bytes", num, size)
|
||||
|
||||
// Generate a random image.
|
||||
img, err := random.Image(size, num)
|
||||
if err != nil {
|
||||
s.error.Printf("ERROR (random.Image): %s", err)
|
||||
serve.Error(w, err)
|
||||
return
|
||||
}
|
||||
serve.Manifest(w, img)
|
||||
}
|
||||
|
|
|
|||
95
cmd/random/main.go
Normal file
95
cmd/random/main.go
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"cloud.google.com/go/compute/metadata"
|
||||
"cloud.google.com/go/logging"
|
||||
"github.com/google/go-containerregistry/pkg/v1/random"
|
||||
"github.com/imjasonh/kontain.me/pkg/serve"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
projectID, err := metadata.ProjectID()
|
||||
if err != nil {
|
||||
log.Fatalf("metadata.ProjectID: %v", err)
|
||||
}
|
||||
client, err := logging.NewClient(ctx, projectID)
|
||||
if err != nil {
|
||||
log.Fatalf("logging.NewClient: %v", err)
|
||||
}
|
||||
lg := client.Logger("server")
|
||||
|
||||
http.Handle("/v2/", &server{
|
||||
info: lg.StandardLogger(logging.Info),
|
||||
error: lg.StandardLogger(logging.Error),
|
||||
})
|
||||
|
||||
log.Println("Starting...")
|
||||
port := os.Getenv("PORT")
|
||||
if port == "" {
|
||||
port = "8080"
|
||||
log.Printf("Defaulting to port %s", port)
|
||||
}
|
||||
log.Printf("Listening on port %s", port)
|
||||
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
|
||||
}
|
||||
|
||||
type server struct {
|
||||
info, error *log.Logger
|
||||
}
|
||||
|
||||
func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
s.info.Println("handler:", r.Method, r.URL)
|
||||
path := strings.TrimPrefix(r.URL.String(), "/v2/")
|
||||
|
||||
switch {
|
||||
case path == "":
|
||||
// API Version check.
|
||||
w.Header().Set("Docker-Distribution-API-Version", "registry/2.0")
|
||||
return
|
||||
case strings.Contains(path, "/manifests/"):
|
||||
s.serveRandomManifest(w, r)
|
||||
case strings.Contains(path, "/blobs/"):
|
||||
serve.Blob(w, r)
|
||||
default:
|
||||
serve.Error(w, serve.ErrNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
// Capture up to 99 layers of up to 99.9MB each.
|
||||
var randomTagRE = regexp.MustCompile("([0-9]{1,2})x([0-9]{1,8})")
|
||||
|
||||
// random.kontain.me:3x10mb
|
||||
// random.kontain.me(:latest) -> 1x10mb
|
||||
func (s *server) serveRandomManifest(w http.ResponseWriter, r *http.Request) {
|
||||
tag := strings.TrimPrefix(r.URL.Path, "/v2/manifests/")
|
||||
var num, size int64 = 1, 10000000 // 10MB
|
||||
|
||||
s.info.Println("TAG", tag)
|
||||
|
||||
// Captured requested num + size from tag.
|
||||
all := randomTagRE.FindStringSubmatch(tag)
|
||||
if len(all) >= 3 {
|
||||
num, _ = strconv.ParseInt(all[1], 10, 64)
|
||||
size, _ = strconv.ParseInt(all[2], 10, 64)
|
||||
}
|
||||
s.info.Printf("generating random image with %d layers of %d bytes", num, size)
|
||||
|
||||
// Generate a random image.
|
||||
img, err := random.Image(size, num)
|
||||
if err != nil {
|
||||
s.error.Printf("ERROR (random.Image): %s", err)
|
||||
serve.Error(w, err)
|
||||
return
|
||||
}
|
||||
serve.Manifest(w, img)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue