From b6b6a55059371c57210c421831d7393f13411f41 Mon Sep 17 00:00:00 2001 From: Jason Hall Date: Fri, 10 May 2019 10:38:41 -0400 Subject: [PATCH] split out random to its own image --- README.md | 42 +++++++++----- cmd/buildpack/kodata/favicon.ico | Bin 4286 -> 0 bytes cmd/buildpack/main.go | 1 - cmd/ko/kodata/index.html | 23 +++++++- cmd/ko/main.go | 35 +----------- cmd/random/main.go | 95 +++++++++++++++++++++++++++++++ deploy.sh | 7 +++ test.sh | 10 ++++ 8 files changed, 162 insertions(+), 51 deletions(-) delete mode 100644 cmd/buildpack/kodata/favicon.ico create mode 100644 cmd/random/main.go create mode 100755 test.sh diff --git a/README.md b/README.md index 05086f8..f9ddb58 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,40 @@ -# kontain.me +**kontain.me** serves Docker container images generated on-demand at the +time they are requested. -[kontain.me](https://kontain.me) serves Docker containter images generated -on-demand at the time they are requested. +# `random.kontain.me` -`docker pull kontain.me/random:latest` 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, +`docker pull random.kontain.me/random:latest` 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, `kontain.me/random:4x100` generates a random image of 4 layers of 100 random bytes each. -`docker pull kontain.me/ko/[import path]` serves an image containing a Go -binary fetched using `go get` and built into a container image using -[`ko`](https://github.com/google/ko/). For example, `docker pull -kontain.me/ko/github.com/google/ko/cmd/ko` will fetch, build and (eventually) -serve a Docker image containing `ko` itself. _Koception!_ +# `kontain.me` -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 +`docker pull kontain.me/ko/[import path]` serves an image +containing a Go binary fetched using `go get` and built into a +container image using [ko](https://github.com/google/ko). + +For example, `docker pull kontain.me/ko/github.com/google/ko/cmd/ko` will fetch, +build and (eventually) serve a Docker image containing `ko` itself. +_Koception!_ + +# `cnb.kontain.me` + +`docker pull cnb.kontain.me/[ghuser]/[ghrepo]:[revision]` serves +an image fetched from source on GitHub and built using [CNCF Buildpacks](https://buildpacks.io) + +For example, `docker pull cnb.kontain.me/buildpack/sample-java-app:b032838` fetches, builds +and serves a [sample Java app](https://github.com/buildpack/sample-java-app). + +# Caveats + +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 faster. -## How it works +# How it works The service is implemented using [Google Cloud Run](https://cloud.google.com/run), with a [custom domain diff --git a/cmd/buildpack/kodata/favicon.ico b/cmd/buildpack/kodata/favicon.ico deleted file mode 100644 index 0c34bfd1a222dd07116a82b324108ce3f5c9ecf5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4286 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.me serves Docker container images generated on-demand at the time they are requested.

-

docker pull kontain.me/random:latest serves an image containing +

random.kontain.me

+ +

docker pull random.kontain.me/random:latest 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, kontain.me/random:4x100 generates a random image of 4 layers of 100 random bytes each. +

kontain.me

+

docker pull kontain.me/ko/[import path] serves an image containing a Go binary fetched using go get and built into a container image using ko. For example, + href="https://github.com/google/ko">ko.

+ +

For example, docker pull kontain.me/ko/github.com/google/ko/cmd/ko will fetch, build and (eventually) serve a Docker image containing ko itself. Koception!

+

cnb.kontain.me

+ +

docker pull cnb.kontain.me/[ghuser]/[ghrepo]:[revision] serves +an image fetched from source on GitHub and built using CNCF Buildpacks.

+ +

For example, docker pull + cnb.kontain.me/buildpack/sample-java-app:b032838 fetches, builds +and serves a sample Java + app.

+ +

Caveats

+

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 diff --git a/cmd/ko/main.go b/cmd/ko/main.go index 17d070a..5bd0e0e 100644 --- a/cmd/ko/main.go +++ b/cmd/ko/main.go @@ -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) -} diff --git a/cmd/random/main.go b/cmd/random/main.go new file mode 100644 index 0000000..5453b80 --- /dev/null +++ b/cmd/random/main.go @@ -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) +} diff --git a/deploy.sh b/deploy.sh index 1f2f431..efae233 100755 --- a/deploy.sh +++ b/deploy.sh @@ -2,6 +2,13 @@ set -euxo pipefail +KO_DOCKER_REPO=gcr.io/kontainme ko publish -P ./cmd/random && \ +gcloud --project=kontainme beta run deploy random \ + --image=gcr.io/kontainme/github.com/imjasonh/kontain.me/cmd/random \ + --memory=2Gi \ + --concurrency=1 \ + --region=us-central1 + KO_DOCKER_REPO=gcr.io/kontainme ko publish -P ./cmd/ko && \ gcloud --project=kontainme beta run deploy app \ --image=gcr.io/kontainme/github.com/imjasonh/kontain.me/cmd/ko \ diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..87291f5 --- /dev/null +++ b/test.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -euxo pipefail + +docker pull random.kontain.me/random +docker pull random.kontain.me/random:8x80 + +docker pull kontain.me/ko/github.com/knative/build/cmd/controller + +docker pull cnb.kontain.me/buildpack/sample-java-app