Skip to content

Commit ebf9586

Browse files
committed
add e2e, and update dockerfile
1 parent 4fb1395 commit ebf9586

15 files changed

+701
-1
lines changed

artifacts/images/custom.Dockerfile

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Build the manager binary
2+
FROM golang:1.19 as builder
3+
4+
WORKDIR /workspace
5+
6+
COPY go.mod go.mod
7+
COPY go.sum go.sum
8+
COPY e2e/ e2e/
9+
COPY vendor/ vendor/
10+
11+
RUN CGO_ENABLED=0 GO111MODULE=on GOOS=linux GOARCH=amd64 go build -mod=vendor -a -o testapp ./e2e/customoperator/app/main.go
12+
13+
14+
FROM ubuntu:focal
15+
16+
17+
RUN apt-get update && \
18+
apt-get install --no-install-recommends -y \
19+
ca-certificates \
20+
curl \
21+
iputils-ping \
22+
tcpdump \
23+
iproute2 \
24+
iptables \
25+
net-tools \
26+
telnet \
27+
lsof \
28+
linux-tools-generic \
29+
sudo && \
30+
apt-get clean && \
31+
rm -rf /var/log/*log /var/lib/apt/lists/* /var/log/apt/* /var/lib/dpkg/*-old /var/cache/debconf/*-old
32+
33+
WORKDIR /
34+
COPY --from=builder /workspace/testapp .
35+
ENTRYPOINT ["/testapp"]

artifacts/images/proxy.Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ COPY artifacts/ artifacts/
88
COPY pkg/ pkg/
99
COPY vendor/ vendor/
1010

11-
RUN CGO_ENABLED=0 GO111MODULE=on go build -mod=vendor -a -o kridge-proxy ./pkg/cmd/proxy/main.go
11+
RUN CGO_ENABLED=0 GO111MODULE=on GOOS=linux GOARCH=amd64 go build -mod=vendor -a -o kridge-proxy ./pkg/cmd/proxy/main.go
1212

1313
FROM ubuntu:focal
1414

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
Copyright 2023 The KusionStack Authors.
3+
Modified from Kruise code, Copyright 2021 The Kruise Authors.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package controller
19+
20+
import (
21+
"context"
22+
"os"
23+
24+
v1 "k8s.io/api/core/v1"
25+
"k8s.io/client-go/util/workqueue"
26+
ctrl "sigs.k8s.io/controller-runtime"
27+
"sigs.k8s.io/controller-runtime/pkg/client"
28+
"sigs.k8s.io/controller-runtime/pkg/event"
29+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
30+
"sigs.k8s.io/controller-runtime/pkg/source"
31+
)
32+
33+
var (
34+
podName, podNamespace string
35+
)
36+
37+
// ManagerStateReconciler reconciles a ManagerState object
38+
type PodReconciler struct {
39+
client.Client
40+
}
41+
42+
func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Result, err error) {
43+
return reconcile.Result{}, nil
44+
}
45+
46+
// SetupWithManager sets up the controller with the Manager.
47+
func (r *PodReconciler) SetupWithManager(mgr ctrl.Manager) error {
48+
podNamespace = os.Getenv("POD_NAMESPACE")
49+
podName = os.Getenv("POD_NAME")
50+
// default handler.EnqueueRequestForObject
51+
return ctrl.NewControllerManagedBy(mgr).
52+
For(&v1.Pod{}).
53+
Watches(&source.Kind{Type: &v1.Pod{}}, &enqueueHandler{Client: r.Client, kind: "Pod"}).
54+
Watches(&source.Kind{Type: &v1.ConfigMap{}}, &enqueueHandler{Client: r.Client, kind: "ConfigMap"}).
55+
Complete(r)
56+
}
57+
58+
type enqueueHandler struct {
59+
client.Client
60+
kind string
61+
}
62+
63+
func (e *enqueueHandler) Create(event event.CreateEvent, q workqueue.RateLimitingInterface) {
64+
add(e.Client, event.Object.GetNamespace(), e.kind)
65+
}
66+
67+
func (e *enqueueHandler) Update(event event.UpdateEvent, q workqueue.RateLimitingInterface) {
68+
add(e.Client, event.ObjectNew.GetNamespace(), e.kind)
69+
}
70+
71+
func (e *enqueueHandler) Delete(event event.DeleteEvent, q workqueue.RateLimitingInterface) {
72+
add(e.Client, event.Object.GetNamespace(), e.kind)
73+
}
74+
75+
func (e *enqueueHandler) Generic(event event.GenericEvent, q workqueue.RateLimitingInterface) {
76+
add(e.Client, event.Object.GetNamespace(), e.kind)
77+
}
+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package controller
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"strings"
8+
"time"
9+
10+
v1 "k8s.io/api/core/v1"
11+
"k8s.io/apimachinery/pkg/api/errors"
12+
"k8s.io/apimachinery/pkg/types"
13+
"k8s.io/apimachinery/pkg/util/sets"
14+
"k8s.io/client-go/util/retry"
15+
"k8s.io/klog/v2"
16+
"sigs.k8s.io/controller-runtime/pkg/client"
17+
)
18+
19+
var (
20+
cmName = "test-resource-recorder"
21+
)
22+
23+
func initConfigMap(c client.Client) *v1.ConfigMap {
24+
//podName := os.Getenv("POD_NAME")
25+
cm := &v1.ConfigMap{}
26+
cm.Name = cmName
27+
cm.Namespace = podNamespace
28+
c.Create(context.TODO(), cm)
29+
return cm
30+
}
31+
32+
func add(c client.Client, namespace, kind string) error {
33+
if namespace == "" || kind == "" {
34+
return nil
35+
}
36+
key := podName
37+
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
38+
cm := &v1.ConfigMap{}
39+
if err := c.Get(context.TODO(), types.NamespacedName{Name: cmName, Namespace: podNamespace}, cm); err != nil {
40+
if !errors.IsNotFound(err) {
41+
return err
42+
}
43+
cm = initConfigMap(c)
44+
}
45+
if cm.Data == nil {
46+
cm.Data = map[string]string{}
47+
}
48+
val, _ := cm.Data[key]
49+
sto := &store{}
50+
if val == "" {
51+
sto.Kinds = map[string]string{}
52+
} else {
53+
json.Unmarshal([]byte(val), sto)
54+
}
55+
names, _ := sto.Kinds[kind]
56+
nameSet := list(names)
57+
if nameSet.Has(namespace) {
58+
return nil
59+
}
60+
nameSet.Insert(namespace)
61+
sto.Kinds[kind] = toString(nameSet)
62+
bt, _ := json.Marshal(sto)
63+
cm.Data[key] = string(bt)
64+
return c.Update(context.TODO(), cm)
65+
})
66+
}
67+
68+
func Checker(ctx context.Context, c client.Client) {
69+
cm := &v1.ConfigMap{}
70+
for {
71+
resources := map[string]sets.Set[string]{}
72+
<-time.After(20 * time.Second)
73+
74+
select {
75+
case <-ctx.Done():
76+
return
77+
default:
78+
}
79+
80+
if err := c.Get(context.TODO(), types.NamespacedName{Name: cmName, Namespace: podNamespace}, cm); err != nil {
81+
klog.Errorf("fail to get configMap %s", cmName)
82+
continue
83+
}
84+
if cm.Data == nil {
85+
klog.Infof("nil configmap data")
86+
continue
87+
}
88+
for pod, val := range cm.Data {
89+
sto := &store{}
90+
if err := json.Unmarshal([]byte(val), sto); err != nil {
91+
klog.Errorf("fail to unmarshal store, %v", err)
92+
}
93+
if sto.Kinds == nil {
94+
continue
95+
}
96+
for kind, names := range sto.Kinds {
97+
set, ok := resources[kind]
98+
if !ok {
99+
set = list(names)
100+
resources[kind] = set
101+
continue
102+
}
103+
nameList := list(names).UnsortedList()
104+
for _, name := range nameList {
105+
if set.Has(name) {
106+
msg := fmt.Sprintf("conflict namespace %s in store, pod: %s", name, pod)
107+
klog.Errorf(msg)
108+
<-time.After(20 * time.Second)
109+
panic(msg)
110+
}
111+
set.Insert(name)
112+
}
113+
resources[kind] = set
114+
}
115+
}
116+
}
117+
}
118+
119+
func list(val string) sets.Set[string] {
120+
res := sets.New[string]()
121+
if val == "" {
122+
return res
123+
}
124+
125+
res.Insert(strings.Split(val, ",")...)
126+
return res
127+
}
128+
129+
func toString(names sets.Set[string]) string {
130+
return strings.Join(sets.List(names), ",")
131+
}
132+
133+
type store struct {
134+
Kinds map[string]string
135+
}

e2e/customoperator/app/main.go

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
Copyright 2023 The KusionStack Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"flag"
21+
"math/rand"
22+
_ "net/http/pprof"
23+
"os"
24+
"time"
25+
26+
"github.com/spf13/pflag"
27+
"k8s.io/apimachinery/pkg/runtime"
28+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
29+
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
30+
_ "k8s.io/client-go/plugin/pkg/client/auth"
31+
"k8s.io/client-go/tools/leaderelection/resourcelock"
32+
"k8s.io/klog/v2"
33+
"k8s.io/klog/v2/klogr"
34+
ctrl "sigs.k8s.io/controller-runtime"
35+
"sigs.k8s.io/controller-runtime/pkg/healthz"
36+
"sigs.k8s.io/controller-runtime/pkg/manager"
37+
38+
appcontroller "github.com/KusionStack/kridge/e2e/customoperator/app/controller"
39+
)
40+
41+
var (
42+
scheme = runtime.NewScheme()
43+
setupLog = ctrl.Log.WithName("setup")
44+
)
45+
46+
func init() {
47+
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
48+
//+kubebuilder:scaffold:scheme
49+
}
50+
51+
// +kubebuilder:rbac:groups=core,resources=events,verbs=get;list;watch;create;update;patch;delete
52+
53+
func main() {
54+
55+
klog.InitFlags(nil)
56+
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
57+
pflag.Parse()
58+
ctrl.SetLogger(klogr.New())
59+
60+
rand.Seed(time.Now().UnixNano())
61+
62+
cfg := ctrl.GetConfigOrDie()
63+
cfg.UserAgent = "testapp"
64+
65+
mgr, err := manager.New(cfg, ctrl.Options{
66+
Scheme: scheme,
67+
LeaderElection: true,
68+
LeaderElectionID: "testapp",
69+
LeaderElectionNamespace: os.Getenv("POD_NAMESPACE"),
70+
LeaderElectionResourceLock: resourcelock.LeasesResourceLock,
71+
})
72+
if err != nil {
73+
setupLog.Error(err, "unable to start manager")
74+
os.Exit(1)
75+
}
76+
77+
ctx := ctrl.SetupSignalHandler()
78+
79+
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
80+
setupLog.Error(err, "unable to set up health check")
81+
os.Exit(1)
82+
}
83+
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
84+
setupLog.Error(err, "unable to set up ready check")
85+
os.Exit(1)
86+
}
87+
88+
go func() {
89+
setupLog.Info("wait webhook ready")
90+
91+
if err = (&appcontroller.PodReconciler{
92+
Client: mgr.GetClient(),
93+
}).SetupWithManager(mgr); err != nil {
94+
setupLog.Error(err, "unable to create controller", "controller", "Recorder")
95+
os.Exit(1)
96+
}
97+
}()
98+
99+
go func() {
100+
<-time.After(20 * time.Second)
101+
appcontroller.Checker(ctx, mgr.GetClient())
102+
}()
103+
setupLog.Info("starting manager")
104+
if err := mgr.Start(ctx); err != nil {
105+
setupLog.Error(err, "problem running manager")
106+
os.Exit(1)
107+
}
108+
}

0 commit comments

Comments
 (0)