Skip to content

Commit c94b87e

Browse files
committed
improve
1 parent 4837ff1 commit c94b87e

File tree

8 files changed

+168
-219
lines changed

8 files changed

+168
-219
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// Copyright (c) 2023 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License.AGPL.txt in the project root for license information.
4+
5+
package cmd
6+
7+
import (
8+
"context"
9+
"fmt"
10+
"path/filepath"
11+
"time"
12+
13+
"github.com/sirupsen/logrus"
14+
"github.com/spf13/cobra"
15+
"github.com/spf13/viper"
16+
17+
"github.com/gitpod-io/gitpod/common-go/log"
18+
corev1 "k8s.io/api/core/v1"
19+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
20+
"k8s.io/client-go/kubernetes"
21+
"k8s.io/client-go/tools/clientcmd"
22+
)
23+
24+
var componentCmdOpt struct {
25+
image string
26+
namespace string
27+
component string
28+
labels string
29+
}
30+
31+
var componentCmd = &cobra.Command{
32+
Use: "component",
33+
Short: "waits for component to become latest build of current installer build",
34+
PreRun: func(cmd *cobra.Command, args []string) {
35+
err := viper.BindPFlags(cmd.Flags())
36+
if err != nil {
37+
log.WithError(err).Fatal("cannot bind Viper to pflags")
38+
}
39+
},
40+
Run: func(cmd *cobra.Command, args []string) {
41+
if componentCmdOpt.image == "" {
42+
log.Fatal("Target image should be defined")
43+
}
44+
timeout := getTimeout()
45+
log.WithField("timeout", timeout.String()).WithFields(logrus.Fields{"image": componentCmdOpt.image, "component": componentCmdOpt.component, "namespace": componentCmdOpt.namespace, "labels": componentCmdOpt.labels}).Info("start to wait component")
46+
ctx, cancel := context.WithTimeout(cmd.Context(), timeout)
47+
defer cancel()
48+
49+
err := waitPodsImage(ctx)
50+
51+
if err != nil {
52+
log.WithError(err).Fatal("failed to wait service")
53+
} else {
54+
log.Info("service is ready")
55+
}
56+
},
57+
}
58+
59+
func checkPodsImage(ctx context.Context, k8sClient *kubernetes.Clientset) (bool, error) {
60+
pods, err := k8sClient.CoreV1().Pods(componentCmdOpt.namespace).List(ctx, metav1.ListOptions{
61+
LabelSelector: componentCmdOpt.labels,
62+
})
63+
if err != nil {
64+
return false, fmt.Errorf("cannot get pod list: %w", err)
65+
}
66+
if len(pods.Items) == 0 {
67+
return false, fmt.Errorf("no pods found")
68+
}
69+
readyCount := 0
70+
for _, pod := range pods.Items {
71+
for _, container := range pod.Spec.Containers {
72+
if container.Name == componentCmdOpt.component {
73+
if container.Image != componentCmdOpt.image {
74+
return false, fmt.Errorf("image is not the same: %s != %s", container.Image, componentCmdOpt.image)
75+
}
76+
for _, condition := range pod.Status.Conditions {
77+
if condition.Type == corev1.PodReady {
78+
if condition.Status == corev1.ConditionTrue {
79+
readyCount += 1
80+
} else {
81+
return false, fmt.Errorf("pod is not ready")
82+
}
83+
}
84+
}
85+
}
86+
}
87+
}
88+
log.Infof("ready pods: %d/%d", readyCount, len(pods.Items))
89+
return readyCount == len(pods.Items), nil
90+
}
91+
92+
func waitPodsImage(ctx context.Context) error {
93+
kubeConfigPath := filepath.Join("/home/gitpod", ".kube", "config")
94+
k8sCfg, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath)
95+
if err != nil {
96+
return fmt.Errorf("cannot get in cluster config: %w", err)
97+
}
98+
k8sClient, err := kubernetes.NewForConfig(k8sCfg)
99+
if err != nil {
100+
return fmt.Errorf("cannot create k8s client: %w", err)
101+
}
102+
ok := false
103+
for {
104+
select {
105+
case <-ctx.Done():
106+
if ok {
107+
return nil
108+
}
109+
return ctx.Err()
110+
default:
111+
ok, err := checkPodsImage(ctx, k8sClient)
112+
if err != nil {
113+
log.WithError(err).Error("image check failed")
114+
time.Sleep(5 * time.Second)
115+
continue
116+
}
117+
if ok {
118+
return nil
119+
}
120+
time.Sleep(5 * time.Second)
121+
}
122+
}
123+
}
124+
125+
func init() {
126+
rootCmd.AddCommand(componentCmd)
127+
componentCmd.Flags().StringVar(&componentCmdOpt.image, "image", "", "The latest image of current installer build")
128+
componentCmd.Flags().StringVar(&componentCmdOpt.namespace, "namespace", "", "The namespace of deployment")
129+
componentCmd.Flags().StringVar(&componentCmdOpt.component, "component", "", "Component name of deployment")
130+
componentCmd.Flags().StringVar(&componentCmdOpt.labels, "labels", "", "Labels of deployment")
131+
132+
_ = componentCmd.MarkFlagRequired("image")
133+
_ = componentCmd.MarkFlagRequired("namespace")
134+
_ = componentCmd.MarkFlagRequired("component")
135+
_ = componentCmd.MarkFlagRequired("labels")
136+
}

components/service-waiter/cmd/public-api-server.go

Lines changed: 0 additions & 50 deletions
This file was deleted.

components/service-waiter/cmd/server.go

Lines changed: 0 additions & 134 deletions
This file was deleted.

components/service-waiter/go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/sirupsen/logrus v1.9.3
1111
github.com/spf13/cobra v1.4.0
1212
github.com/spf13/viper v1.7.0
13+
k8s.io/api v0.27.3
1314
k8s.io/apimachinery v0.27.3
1415
k8s.io/client-go v0.0.0-00010101000000-000000000000
1516
)
@@ -33,6 +34,7 @@ require (
3334
github.com/google/uuid v1.3.0 // indirect
3435
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
3536
github.com/hashicorp/hcl v1.0.0 // indirect
37+
github.com/imdario/mergo v0.3.6 // indirect
3638
github.com/inconshreveable/mousetrap v1.0.0 // indirect
3739
github.com/josharian/intern v1.0.0 // indirect
3840
github.com/json-iterator/go v1.1.12 // indirect
@@ -64,7 +66,6 @@ require (
6466
gopkg.in/ini.v1 v1.51.0 // indirect
6567
gopkg.in/yaml.v2 v2.4.0 // indirect
6668
gopkg.in/yaml.v3 v3.0.1 // indirect
67-
k8s.io/api v0.27.3 // indirect
6869
k8s.io/klog/v2 v2.90.1 // indirect
6970
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
7071
k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect

components/service-waiter/go.sum

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)