Skip to content

Commit

Permalink
Merge pull request #154 from datawire/lukeshu/rhs/k8s-args/kubeapply
Browse files Browse the repository at this point in the history
k8s-args: Part 2A: Add {{image}} function to kubeapply
  • Loading branch information
rhs committed Aug 15, 2019
2 parents 585e883 + da13e3e commit 8ba1e6f
Show file tree
Hide file tree
Showing 15 changed files with 240 additions and 19 deletions.
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*
!go.mod
!go.sum
!internal/
!pkg/
!cmd/
!vendor/
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
/.firewall.lock
/.cluster.lock
/vendor/
/build-aux/test-registry.pid
/build-aux/test-registry.log

# --- IntelliJ IDEA ---
.idea
Expand Down
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM golang:1.12-alpine as builder
WORKDIR /app

COPY . .

RUN go install -mod=vendor ./cmd/httptest

RUN ls /go/bin

FROM alpine:3.10.1
COPY --from=builder /go/bin/httptest /usr/local/bin/httptest
ENTRYPOINT ["/usr/local/bin/httptest"]
17 changes: 14 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Use the versions of teleproxy and kubeapply built here, instead of
# versions pinned by build-aux.
include build-aux/prelude.mk
TELEPROXY = bin_$(GOHOSTHOS)_$(GOHOSTARCH)/teleproxy
KUBEAPPLY = bin_$(GOHOSTHOS)_$(GOHOSTARCH)/kubeapply
TELEPROXY = bin_$(GOHOSTOS)_$(GOHOSTARCH)/teleproxy
KUBEAPPLY = bin_$(GOHOSTOS)_$(GOHOSTARCH)/kubeapply

include build-aux/kubernaut-ui.mk
include build-aux/common.mk
Expand All @@ -12,8 +12,19 @@ include build-aux/docker.mk
include build-aux/help.mk
include build-aux/k8s.mk
include build-aux/teleproxy.mk
include build-aux/pidfile.mk

check: $(_kubernaut-ui.KUBECONFIG)
export DOCKER_REGISTRY = $(docker.LOCALHOST):31000

build-aux/test-registry.pid: $(_kubernaut-ui.KUBECONFIG) $(KUBEAPPLY)
$(KUBEAPPLY) -f build-aux/docker-registry.yaml
kubectl port-forward --namespace=docker-registry deployment/registry 31000:5000 >build-aux/test-registry.log 2>&1 & echo $$! > $@
while ! curl -i http://localhost:31000/ 2>/dev/null; do sleep 1; done
$(_kubernaut-ui.KUBECONFIG).clean: build-aux/test-registry.pid.clean
clean: build-aux/test-registry.pid.clean
rm -f build-aux/test-registry.log

build-aux/go-test.tap: vendor build-aux/test-registry.pid

# Utility targets

Expand Down
7 changes: 6 additions & 1 deletion build-aux/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<!-- -*- fill-column: 100 -*- -->
# Datawire build-aux CHANGELOG

- 2019-08-13: Fix race condition in `make clobber` where it attempted to use compiled programs used
for cleanup, after the programs themselves had already been deleted.

- 2019-07-10: `var.mk`: Introduce

- 2019-07-05: `build-aux-push`: Work around problem with `git subtree`; avoid accidentally pushing
proprietary code to build-aux.git.

Expand All @@ -19,7 +24,7 @@
- 2019-06-20: `go-mod.mk`: For each binary, generate a `BIN.opensource.tar.gz` file.
- 2019-06-20: `go-workspace.mk`: Remove.

- 2019-05-31: `go-modmk`: Add `go doc` target to run `godoc -http`.
- 2019-05-31: `go-mod.mk`: Add `go doc` target to run `godoc -http`.

- 2019-05-01: BREAKING CHANGE: `docker.mk`: Don't include `kuberanut-ui.mk`.
- 2019-05-01: BREAKING CHANGE: `teleproxy.mk`: Don't include `kuberanut-ui.mk`.
Expand Down
8 changes: 8 additions & 0 deletions build-aux/HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
value.
- Make sure to pass `--fail` to `curl` when downloading things;
otherwise it will silently save 404 HTML/XML pages.
- Don't depend on anything in ./build-aux/bin/ during clean and
clobber rules. The `prelude.mk` cleanup might remove it before
your cleanup bit runs. For Go programs, `cd` to the program's
sourcedirectory, and use `go run .` to run it:

cd $(dir $(_myfile.mk))bin-go/PROGRAM && GO111MODULE=on go run . ARGS...

Only tolerate that grossness in your cleanup rules.

## Naming conventions

Expand Down
7 changes: 5 additions & 2 deletions build-aux/docker.mk
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,11 @@ _docker.port-forward = $(dir $(_docker.mk))docker-port-forward
docker push '$(DOCKER_IMAGE)'
.PHONY: %.docker.push

_clean-docker: $(FLOCK)
$(FLOCK) $(_docker.port-forward).lock rm $(_docker.port-forward).lock
# This `go run` bit is gross, compared to just depending on and using
# $(FLOCK). But if the user runs `make clobber`, the prelude.mk
# cleanup might delete $(FLOCK) before we get to run it.
_clean-docker:
cd $(dir $(_docker.mk))bin-go/flock && GO111MODULE=on go run . $(abspath $(_docker.port-forward).lock) rm $(abspath $(_docker.port-forward).lock)
rm -f $(_docker.port-forward).log
rm -f $(dir $(_docker.mk))docker-registry.yaml.o
clean: _clean-docker
Expand Down
7 changes: 5 additions & 2 deletions build-aux/kubernaut.mk
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ GUBERNAUT ?= $(build-aux.bindir)/gubernaut
$(GUBERNAUT) -release $$(cat $<)
$(GUBERNAUT) -claim $$(cat $<) -output $@

%.knaut.clean: $(GUBERNAUT)
if [ -e $*.knaut.claim ]; then $(GUBERNAUT) -release $$(cat $*.knaut.claim); fi
# This `go run` bit is gross, compared to just depending on and using
# $(GUBERNAUT). But if the user runs `make clobber`, the prelude.mk
# cleanup might delete $(GUBERNAUT) before we get to run it.
%.knaut.clean:
if [ -e $*.knaut.claim ]; then cd $(dir $(_kubernaut.mk))bin-go/gubernaut && GO111MODULE=on go run . -release $$(cat $(abspath $*.knaut.claim)); fi
rm -f $*.knaut $*.knaut.claim
.PHONY: %.knaut.clean

Expand Down
23 changes: 23 additions & 0 deletions cmd/httptest/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"log"
"net/http"
"os"
)

func main() {
body := os.Getenv("HTTPTEST_BODY")
if body == "" {
body = "HTTPTEST"
}

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte(body))
if err != nil {
log.Print(err)
}
})

log.Fatal(http.ListenAndServe(":8080", nil))
}
19 changes: 15 additions & 4 deletions cmd/teleproxy/teleproxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,15 @@ import (

const ClusterFile = "../../build-aux/cluster.knaut"

var noDocker error

func TestMain(m *testing.M) {
testprocess.Dispatch()
dtest.WithMachineLock(func() {
dtest.K8sApply(ClusterFile, "../../k8s")
_, noDocker = exec.LookPath("docker")
if noDocker == nil {
dtest.K8sApply(ClusterFile, "../../k8s")
}
os.Exit(m.Run())
})
}
Expand Down Expand Up @@ -98,20 +103,26 @@ func teleproxyCluster() {
var smoke = testprocess.MakeSudo(teleproxyCluster)

func TestSmoke(t *testing.T) {
if noDocker != nil {
t.Skip(noDocker)
}
withInterrupt(t, smoke, func() {
poll(t, "http://teleproxied-httpbin/status/200")
poll(t, "http://httptarget")
})
}

var orig = testprocess.MakeSudo(teleproxyCluster)
var dup = testprocess.MakeSudo(teleproxyCluster)

func TestAlreadyRunning(t *testing.T) {
if noDocker != nil {
t.Skip(noDocker)
}
withInterrupt(t, orig, func() {
if poll(t, "http://teleproxied-httpbin/status/200") {
if poll(t, "http://httptarget") {
err := dup.Run()
t.Logf("ERROR: %v", err)
resp, err := get("http://teleproxied-httpbin/status/200")
resp, err := get("http://httptarget")
if err != nil {
t.Errorf("duplicate teleproxy killed the first one: %v", err)
return
Expand Down
36 changes: 36 additions & 0 deletions k8s/httptarget-alt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# @TEMPLATE@
---
apiVersion: v1
kind: Namespace
metadata:
name: alt
---
kind: Service
apiVersion: v1
metadata:
name: httptarget
namespace: alt
spec:
selector:
pod: httptarget
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: v1
kind: Pod
metadata:
name: httptarget
namespace: alt
labels:
pod: httptarget
spec:
containers:
- name: backend
image: {{image "../Dockerfile"}}
ports:
- containerPort: 80
env:
- name: HTTPTEST_BODY
value: "ALT"
13 changes: 7 additions & 6 deletions k8s/httpbin.yaml → k8s/httptarget.yaml
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
# @TEMPLATE@
---
kind: Service
apiVersion: v1
metadata:
name: teleproxied-httpbin
name: httptarget
spec:
selector:
pod: teleproxied-httpbin
pod: httptarget
ports:
- protocol: TCP
port: 80
targetPort: 80
targetPort: 8080
---
apiVersion: v1
kind: Pod
metadata:
name: teleproxied-httpbin
name: httptarget
labels:
pod: teleproxied-httpbin
pod: httptarget
spec:
containers:
- name: backend
image: kennethreitz/httpbin
image: {{image "../Dockerfile"}}
ports:
- containerPort: 80
26 changes: 26 additions & 0 deletions pkg/k8s/docker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# @TEMPLATE@
---
kind: Service
apiVersion: v1
metadata:
name: httptest
spec:
selector:
pod: httptest
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: v1
kind: Pod
metadata:
name: httptest
labels:
pod: httptest
spec:
containers:
- name: httptest
image: {{image "../../Dockerfile"}}
ports:
- containerPort: 80
63 changes: 62 additions & 1 deletion pkg/k8s/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import (

"github.com/Masterminds/sprig"
ms "github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"

"github.com/datawire/teleproxy/pkg/supervisor"
)

var READY = map[string]func(Resource) bool{
Expand Down Expand Up @@ -259,13 +262,71 @@ func isTemplate(input []byte) bool {
return strings.Contains(string(input), "@TEMPLATE@")
}

func builder(dir string) func(string) (string, error) {
return func(dockerfile string) (string, error) {
return image(dir, dockerfile)
}
}

func image(dir, dockerfile string) (string, error) {
var result string
errs := supervisor.Run("BLD", func(p *supervisor.Process) error {
iidfile, err := ioutil.TempFile("", "iid")
if err != nil {
return err
}
defer os.Remove(iidfile.Name())
err = iidfile.Close()
if err != nil {
return err
}

ctx := filepath.Dir(filepath.Join(dir, dockerfile))
cmd := p.Command("docker", "build", "-f", filepath.Base(dockerfile), ".", "--iidfile", iidfile.Name())
cmd.Dir = ctx
err = cmd.Run()
if err != nil {
return err
}
content, err := ioutil.ReadFile(iidfile.Name())
if err != nil {
return err
}
iid := strings.Split(strings.TrimSpace(string(content)), ":")[1]
short := iid[:12]

registry := strings.TrimSpace(os.Getenv("DOCKER_REGISTRY"))
if registry == "" {
return errors.Errorf("please set the DOCKER_REGISTRY environment variable")
}
tag := fmt.Sprintf("%s/%s", registry, short)

cmd = p.Command("docker", "tag", iid, tag)
err = cmd.Run()
if err != nil {
return err
}

result = tag

cmd = p.Command("docker", "push", tag)
return cmd.Run()
})
if len(errs) > 0 {
return "", errors.Errorf("errors building %s: %v", dockerfile, errs)
}
return result, nil
}

func ExpandResource(path string) (result []byte, err error) {
input, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("%s: %v", path, err)
}
if isTemplate(input) {
tmpl := template.New(filepath.Base(path)).Funcs(sprig.TxtFuncMap())
funcs := sprig.TxtFuncMap()
funcs["image"] = builder(filepath.Dir(path))
tmpl := template.New(filepath.Base(path)).Funcs(funcs)
_, err := tmpl.Parse(string(input))
if err != nil {
return nil, fmt.Errorf("%s: %v", path, err)
Expand Down
Loading

0 comments on commit 8ba1e6f

Please sign in to comment.