Skip to content

Commit 5c7aabd

Browse files
committed
Lab 12, bonus task
1 parent 93876dc commit 5c7aabd

File tree

11 files changed

+119
-6
lines changed

11 files changed

+119
-6
lines changed

app_go/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@
2525
go.work
2626

2727
# End of https://www.toptal.com/developers/gitignore/api/go
28+
29+
30+
/persistent

app_go/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
FROM golang:1.22.0-alpine3.19 as builder
22

3+
RUN ["mkdir", "/empty-dir"]
4+
35
WORKDIR /usr/src/app/
46

57
COPY go.mod *.go /usr/src/app/
@@ -16,6 +18,8 @@ COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.
1618

1719
EXPOSE 5000
1820

21+
VOLUME /persistent
1922
COPY --from=builder /usr/src/app/catfact_webapp /
2023
USER 2004:2004
24+
COPY --from=builder --chown=2004:2004 /empty-dir /persistent
2125
ENTRYPOINT ["/catfact_webapp"]

app_go/main.go

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
package main
22

33
import (
4+
"sync/atomic"
5+
"encoding/binary"
6+
"errors"
7+
"path/filepath"
48
"fmt"
59
"log"
610
"net/http"
11+
"os"
712
"time"
813

914
"github.com/prometheus/client_golang/prometheus"
1015
"github.com/prometheus/client_golang/prometheus/promauto"
1116
"github.com/prometheus/client_golang/prometheus/promhttp"
1217
)
1318

14-
func index(w http.ResponseWriter, r *http.Request) {
19+
const visitsFile = "persistent/visits.bin"
20+
var visits atomic.Uint64
21+
22+
func indexHandler(w http.ResponseWriter, r *http.Request) {
1523
fact, err := catFact()
1624
if err == nil {
1725
w.WriteHeader(http.StatusOK)
@@ -22,6 +30,10 @@ func index(w http.ResponseWriter, r *http.Request) {
2230
}
2331
}
2432

33+
func visitsHandler(w http.ResponseWriter, r *http.Request) {
34+
_, _ = fmt.Fprintf(w, "%d", visits.Load())
35+
}
36+
2537

2638
var (
2739
reqCnt = promauto.NewCounter(prometheus.CounterOpts{
@@ -48,14 +60,42 @@ func noteTimeMiddleware(next http.Handler) http.Handler {
4860
})
4961
}
5062

63+
func countVisitsMiddleware(next http.Handler) http.Handler {
64+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
65+
visits.Add(1) // Atomic increment, no race condition here, so counter
66+
// is always correct
67+
buf := make([]byte, binary.MaxVarintLen64)
68+
binary.LittleEndian.PutUint64(buf, visits.Load())
69+
// Race condition in the order in which threads will write the file out,
70+
// so the file may not be correct, but as the same number of bytes is
71+
// always written out, the counter in the file remains a valid number.
72+
os.WriteFile(visitsFile, buf, 0644)
73+
next.ServeHTTP(w, r)
74+
})
75+
}
76+
77+
78+
func init() {
79+
_ = os.MkdirAll(filepath.Dir(visitsFile), 0755)
80+
buf, err := os.ReadFile(visitsFile)
81+
if err == nil {
82+
visits.Store(binary.LittleEndian.Uint64(buf))
83+
} else if errors.Is(err, os.ErrNotExist) {
84+
visits.Store(0)
85+
} else {
86+
panic(err)
87+
}
88+
}
89+
5190

5291
func main() {
5392
businessLogic := http.NewServeMux()
54-
businessLogic.Handle("/", asHandler(index))
93+
businessLogic.Handle("/", asHandler(indexHandler))
94+
businessLogic.Handle("/visits", asHandler(visitsHandler))
5595
// Note: keeping /metrics under middleware too for consistency with app_py
5696
businessLogic.Handle("/metrics", promhttp.Handler())
5797

58-
wrapped := noteTimeMiddleware(businessLogic)
98+
wrapped := noteTimeMiddleware(countVisitsMiddleware(businessLogic))
5999

60100
hostPort := "0.0.0.0:5000"
61101
_, _ = fmt.Println("Listening on http://" + hostPort)

app_go/main_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
func TestFactLoads(t *testing.T) {
1414
w := httptest.NewRecorder()
1515

16-
index(w, nil)
16+
indexHandler(w, nil)
1717
resp := w.Result()
1818

1919
if resp.StatusCode != http.StatusOK {

k8s/12.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,55 @@ $ kubectl exec app-py-7d7d86657c-twd5l -- cat /persistent/config.json
2727
{"mole": ["hamsters"], "hamster": ["moles"]}
2828
$
2929
```
30+
31+
## ConfigMap env
32+
33+
```sh
34+
$ helm install app-go .
35+
NAME: app-go
36+
LAST DEPLOYED: Mon Apr 22 19:26:23 2024
37+
NAMESPACE: default
38+
STATUS: deployed
39+
REVISION: 1
40+
NOTES:
41+
1. Get the application URL by running these commands:
42+
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
43+
You can watch the status of by running 'kubectl get --namespace default svc -w app-go-app-py'
44+
export SERVICE_IP=$(kubectl get svc --namespace default app-go-app-py --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
45+
echo http://$SERVICE_IP:5000
46+
$ kubectl get po
47+
NAME READY STATUS RESTARTS AGE
48+
app-go-app-py-59f4c5c69d-8fljp 1/1 Running 0 22s
49+
app-go-app-py-59f4c5c69d-bv496 1/1 Running 0 22s
50+
app-go-app-py-59f4c5c69d-jlz6q 1/1 Running 0 22s
51+
app-go-app-py-59f4c5c69d-t2nnn 1/1 Running 0 22s
52+
$ kubectl debug --image=gcc -it app-go-app-py-59f4c5c69d-8fljp --target=app-py
53+
Targeting container "app-py". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
54+
Defaulting debug container name to debugger-864lv.
55+
If you don't see a command prompt, try pressing enter.
56+
root@app-go-app-py-59f4c5c69d-8fljp:/# echo 'main(){setreuid(geteuid(),geteuid());execl("/bin/sh","sh",0);}' > a.c
57+
root@app-go-app-py-59f4c5c69d-8fljp:/# gcc -o a a.c
58+
a.c:1:1: warning: return type defaults to 'int' [-Wimplicit-int]
59+
1 | main(){setreuid(geteuid(),geteuid());execl("/bin/sh","sh",0);}
60+
| ^~~~
61+
a.c: In function 'main':
62+
a.c:1:8: warning: implicit declaration of function 'setreuid' [-Wimplicit-function-declaration]
63+
1 | main(){setreuid(geteuid(),geteuid());execl("/bin/sh","sh",0);}
64+
| ^~~~~~~~
65+
a.c:1:17: warning: implicit declaration of function 'geteuid' [-Wimplicit-function-declaration]
66+
1 | main(){setreuid(geteuid(),geteuid());execl("/bin/sh","sh",0);}
67+
| ^~~~~~~
68+
a.c:1:38: warning: implicit declaration of function 'execl' [-Wimplicit-function-declaration]
69+
1 | main(){setreuid(geteuid(),geteuid());execl("/bin/sh","sh",0);}
70+
| ^~~~~
71+
a.c:1:38: warning: incompatible implicit declaration of built-in function 'execl' [-Wbuiltin-declaration-mismatch]
72+
root@app-go-app-py-59f4c5c69d-8fljp:/# chown 2004:2004 a
73+
root@app-go-app-py-59f4c5c69d-8fljp:/# chmod u+s a
74+
root@app-go-app-py-59f4c5c69d-8fljp:/# exec ./a
75+
$ cat /proc/1/environ | sed 's/\x0/\n/g' | grep seal
76+
seal=2001
77+
monk_seal=century
78+
$ exit
79+
Session ended, the ephemeral container will not be restarted but may be reattached using 'kubectl attach app-go-app-py-59f4c5c69d-8fljp -c debugger-864lv -i -t' if it is still running
80+
$
81+
```

k8s/app-go/charts/label-lib-0.1.0.tgz

338 Bytes
Binary file not shown.

k8s/app-go/files/config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
seal: "2001"
2+
monk_seal: "century"

k8s/app-go/templates/config-map.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: "v1"
2+
kind: ConfigMap
3+
metadata:
4+
name: {{.Release.Name}}-config-map
5+
data:
6+
{{ .Files.Get "files/config.yaml" | indent 2 }}

k8s/app-go/templates/deployment.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ spec:
5252
{{- end }}
5353
env:
5454
{{ include "app-go.environ" . | nindent 12 }}
55+
envFrom:
56+
- configMapRef:
57+
name: {{.Release.Name}}-config-map
5558
{{- with .Values.volumes }}
5659
volumes:
5760
{{- toYaml . | nindent 8 }}

k8s/app-go/values.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ image:
44
repository: kolay0ne/app_go
55
pullPolicy: IfNotPresent
66
# Overrides the image tag whose default is the chart appVersion.
7-
tag: "lab8"
7+
tag: "lab12"
88

99
serviceAccount:
1010
# Specifies whether a service account should be created

monitoring/docker-compose.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ networks:
55
volumes:
66
grafana-storage:
77
py-persistent:
8+
go-persistent:
89

910
services:
1011
app_py:
@@ -22,7 +23,7 @@ services:
2223
- py-persistent:/app/persistent
2324

2425
app_go:
25-
image: kolay0ne/app_go:lab8
26+
image: kolay0ne/app_go:lab12
2627
ports:
2728
- "5500:5000"
2829
logging:
@@ -32,6 +33,8 @@ services:
3233
resources: {limits: {memory: 20M}}
3334
networks:
3435
- prometheus
36+
volumes:
37+
- go-persistent:/persistent
3538

3639
loki:
3740
image: grafana/loki:2.9.2

0 commit comments

Comments
 (0)