-
Notifications
You must be signed in to change notification settings - Fork 5
Feat.support http tunnel #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9a02687
e9de3f8
9ec96f3
2cf73d3
4b2fb62
6aff7a9
320041c
f94781e
498ad06
fe277a1
ec176c3
4309939
40a5e04
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -20,6 +20,7 @@ import ( | |||||||||||||||||||||||||||||
| "github.com/koupleless/module_controller/common/model" | ||||||||||||||||||||||||||||||
| "github.com/koupleless/module_controller/controller/module_deployment_controller" | ||||||||||||||||||||||||||||||
| "github.com/koupleless/module_controller/module_tunnels" | ||||||||||||||||||||||||||||||
| "github.com/koupleless/module_controller/module_tunnels/koupleless_http_tunnel" | ||||||||||||||||||||||||||||||
| "github.com/koupleless/module_controller/module_tunnels/koupleless_mqtt_tunnel" | ||||||||||||||||||||||||||||||
| "github.com/koupleless/module_controller/report_server" | ||||||||||||||||||||||||||||||
| "github.com/koupleless/virtual-kubelet/common/log" | ||||||||||||||||||||||||||||||
|
|
@@ -71,13 +72,20 @@ func main() { | |||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||
| log.G(ctx).WithError(err).Error("failed to parse WORKLOAD_MAX_LEVEL, will be set to 3 default") | ||||||||||||||||||||||||||||||
| workloadMaxLevel = 3 | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| vnodeWorkerNum, err := strconv.Atoi(utils.GetEnv("VNODE_WORKER_NUM", "8")) | ||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||
| log.G(ctx).WithError(err).Error("failed to parse VNODE_WORKER_NUM, will be set to 8 default") | ||||||||||||||||||||||||||||||
| vnodeWorkerNum = 8 | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| kubeConfig := config.GetConfigOrDie() | ||||||||||||||||||||||||||||||
| mgr, err := manager.New(kubeConfig, manager.Options{ | ||||||||||||||||||||||||||||||
| Cache: cache.Options{}, | ||||||||||||||||||||||||||||||
| Metrics: server.Options{ | ||||||||||||||||||||||||||||||
| BindAddress: "0", | ||||||||||||||||||||||||||||||
| BindAddress: ":9090", | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
@@ -88,9 +96,36 @@ func main() { | |||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| tracker.SetTracker(&tracker.DefaultTracker{}) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| tl := &koupleless_mqtt_tunnel.MqttTunnel{ | ||||||||||||||||||||||||||||||
| Cache: mgr.GetCache(), | ||||||||||||||||||||||||||||||
| Client: mgr.GetClient(), | ||||||||||||||||||||||||||||||
| tunnels := make([]tunnel.Tunnel, 0) | ||||||||||||||||||||||||||||||
| moduleTunnels := make([]module_tunnels.ModuleTunnel, 0) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| mqttTunnelEnable := utils.GetEnv("ENABLE_MQTT_TUNNEL", "false") | ||||||||||||||||||||||||||||||
| if mqttTunnelEnable == "true" { | ||||||||||||||||||||||||||||||
|
Comment on lines
+102
to
+103
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Use Boolean Parsing for Environment Variables Currently, environment variables Example using mqttTunnelEnable, err := strconv.ParseBool(utils.GetEnv("ENABLE_MQTT_TUNNEL", "false"))
if err != nil {
log.G(ctx).WithError(err).Error("failed to parse ENABLE_MQTT_TUNNEL, defaulting to false")
mqttTunnelEnable = false
}
if mqttTunnelEnable {
// ...
}
httpTunnelEnable, err := strconv.ParseBool(utils.GetEnv("ENABLE_HTTP_TUNNEL", "false"))
if err != nil {
log.G(ctx).WithError(err).Error("failed to parse ENABLE_HTTP_TUNNEL, defaulting to false")
httpTunnelEnable = false
}
if httpTunnelEnable {
// ...
}Alternatively, create a utility function Also applies to: 113-114 |
||||||||||||||||||||||||||||||
| mqttTl := &koupleless_mqtt_tunnel.MqttTunnel{ | ||||||||||||||||||||||||||||||
| Cache: mgr.GetCache(), | ||||||||||||||||||||||||||||||
| Client: mgr.GetClient(), | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| tunnels = append(tunnels, mqttTl) | ||||||||||||||||||||||||||||||
| moduleTunnels = append(moduleTunnels, mqttTl) | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| httpTunnelEnable := utils.GetEnv("ENABLE_HTTP_TUNNEL", "false") | ||||||||||||||||||||||||||||||
| if httpTunnelEnable == "true" { | ||||||||||||||||||||||||||||||
| httpTunnelListenPort, err := strconv.Atoi(utils.GetEnv("HTTP_TUNNEL_LISTEN_PORT", "7777")) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||
| log.G(ctx).WithError(err).Error("failed to parse HTTP_TUNNEL_LISTEN_PORT, set default port 7777") | ||||||||||||||||||||||||||||||
| httpTunnelListenPort = 7777 | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
Comment on lines
+115
to
+120
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add port range validation for HTTP tunnel. The HTTP tunnel port parsing should include validation to ensure it's within a valid range (1-65535). httpTunnelListenPort, err := strconv.Atoi(utils.GetEnv("HTTP_TUNNEL_LISTEN_PORT", "7777"))
if err != nil {
log.G(ctx).WithError(err).Error("failed to parse HTTP_TUNNEL_LISTEN_PORT, set default port 7777")
httpTunnelListenPort = 7777
+} else if httpTunnelListenPort < 1 || httpTunnelListenPort > 65535 {
+ log.G(ctx).Error("HTTP_TUNNEL_LISTEN_PORT out of valid range (1-65535), set default port 7777")
+ httpTunnelListenPort = 7777
}📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Check: codecov/patch
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| httpTl := &koupleless_http_tunnel.HttpTunnel{ | ||||||||||||||||||||||||||||||
| Cache: mgr.GetCache(), | ||||||||||||||||||||||||||||||
| Client: mgr.GetClient(), | ||||||||||||||||||||||||||||||
| Port: httpTunnelListenPort, | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| tunnels = append(tunnels, httpTl) | ||||||||||||||||||||||||||||||
| moduleTunnels = append(moduleTunnels, httpTl) | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| rcc := vkModel.BuildVNodeControllerConfig{ | ||||||||||||||||||||||||||||||
|
|
@@ -99,11 +134,10 @@ func main() { | |||||||||||||||||||||||||||||
| VPodIdentity: model.ComponentModule, | ||||||||||||||||||||||||||||||
| IsCluster: isCluster, | ||||||||||||||||||||||||||||||
| WorkloadMaxLevel: workloadMaxLevel, | ||||||||||||||||||||||||||||||
| VNodeWorkerNum: vnodeWorkerNum, | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| vc, err := vnode_controller.NewVNodeController(&rcc, []tunnel.Tunnel{ | ||||||||||||||||||||||||||||||
| tl, | ||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||
| vc, err := vnode_controller.NewVNodeController(&rcc, tunnels) | ||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||
| log.G(ctx).Error(err, "unable to set up VNodeController") | ||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||
|
|
@@ -118,9 +152,7 @@ func main() { | |||||||||||||||||||||||||||||
| enableModuleDeploymentController := utils.GetEnv("ENABLE_MODULE_DEPLOYMENT_CONTROLLER", "false") | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if enableModuleDeploymentController == "true" { | ||||||||||||||||||||||||||||||
| mdc, err := module_deployment_controller.NewModuleDeploymentController(env, []module_tunnels.ModuleTunnel{ | ||||||||||||||||||||||||||||||
| tl, | ||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||
| mdc, err := module_deployment_controller.NewModuleDeploymentController(env, moduleTunnels) | ||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||
| log.G(ctx).Error(err, "unable to set up module_deployment_controller") | ||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||
|
|
@@ -133,11 +165,13 @@ func main() { | |||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| err = tl.Start(ctx, clientID, env) | ||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||
| log.G(ctx).WithError(err).Error("failed to start tunnel", tl.Key()) | ||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||
| log.G(ctx).Info("Tunnel started: ", tl.Key()) | ||||||||||||||||||||||||||||||
| for _, t := range tunnels { | ||||||||||||||||||||||||||||||
| err = t.Start(ctx, clientID, env) | ||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||
| log.G(ctx).WithError(err).Error("failed to start tunnel", t.Key()) | ||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||
| log.G(ctx).Info("Tunnel started: ", t.Key()) | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
Comment on lines
+168
to
+174
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve tunnel startup coordination. The current implementation starts tunnels sequentially without proper coordination. Consider:
+const tunnelStartTimeout = 30 * time.Second
for _, t := range tunnels {
- err = t.Start(ctx, clientID, env)
+ startCtx, cancel := context.WithTimeout(ctx, tunnelStartTimeout)
+ err = t.Start(startCtx, clientID, env)
+ cancel()
if err != nil {
log.G(ctx).WithError(err).Error("failed to start tunnel", t.Key())
} else {
log.G(ctx).Info("Tunnel started: ", t.Key())
}
+
+ // Add health check
+ if err := waitForTunnelReady(ctx, t); err != nil {
+ log.G(ctx).WithError(err).Error("tunnel failed health check", t.Key())
+ }
}Consider adding a helper function for tunnel health checks: func waitForTunnelReady(ctx context.Context, t tunnel.Tunnel) error {
// Implementation depends on tunnel interface capabilities
// Could ping the tunnel or check its internal state
return nil
}🧰 Tools🪛 GitHub Check: codecov/patch
|
||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| log.G(ctx).Info("Module controller running") | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,14 +1,19 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package utils | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "context" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/koupleless/arkctl/common/fileutil" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/koupleless/arkctl/v1/service/ark" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/koupleless/module_controller/common/model" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/koupleless/virtual-kubelet/common/log" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/koupleless/virtual-kubelet/common/utils" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vkModel "github.com/koupleless/virtual-kubelet/model" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/sirupsen/logrus" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| corev1 "k8s.io/api/core/v1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| apiErrors "k8s.io/apimachinery/pkg/api/errors" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "sigs.k8s.io/controller-runtime/pkg/client" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "strconv" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "strings" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "time" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -61,6 +66,10 @@ func TranslateHeartBeatDataToNodeInfo(data model.HeartBeatData) vkModel.NodeInfo | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if data.State == "ACTIVATED" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| state = vkModel.NodeStatusActivated | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| labels := map[string]string{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if data.NetworkInfo.ArkletPort != 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| labels[model.LabelKeyOfArkletPort] = strconv.Itoa(data.NetworkInfo.ArkletPort) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return vkModel.NodeInfo{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Metadata: vkModel.NodeMetadata{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Name: data.MasterBizInfo.Name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -71,6 +80,7 @@ func TranslateHeartBeatDataToNodeInfo(data model.HeartBeatData) vkModel.NodeInfo | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NodeIP: data.NetworkInfo.LocalIP, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| HostName: data.NetworkInfo.LocalHostName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CustomLabels: labels, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -150,12 +160,14 @@ func TranslateSimpleBizDataToArkBizInfo(data model.ArkSimpleBizInfoData) *ark.Ar | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func GetContainerStateFromBizState(bizStateIndex string) vkModel.ContainerState { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| switch bizStateIndex { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "RESOLVED": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| switch strings.ToLower(bizStateIndex) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "resolved": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return vkModel.ContainerStateResolved | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "ACTIVATED": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "activated": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return vkModel.ContainerStateActivated | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "DEACTIVATED": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "deactivated": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return vkModel.ContainerStateDeactivated | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "broken": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return vkModel.ContainerStateDeactivated | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return vkModel.ContainerStateWaiting | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -164,11 +176,13 @@ func GetContainerStateFromBizState(bizStateIndex string) vkModel.ContainerState | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func GetArkBizStateFromSimpleBizState(bizStateIndex string) string { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| switch bizStateIndex { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "2": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "RESOLVED" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "resolved" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "3": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "ACTIVATED" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "activated" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "4": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "DEACTIVATED" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "deactivated" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "5": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "broken" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -197,3 +211,39 @@ func GetLatestState(state string, records []ark.ArkBizStateRecord) (time.Time, s | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return latestStateTime, reason, message | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func OnBaseUnreachable(ctx context.Context, info vkModel.UnreachableNodeInfo, env string, k8sClient client.Client) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // base not ready, delete from api server | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node := corev1.Node{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nodeName := utils.FormatNodeName(info.NodeID, env) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err := k8sClient.Get(ctx, client.ObjectKey{Name: nodeName}, &node) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger := log.G(ctx).WithField("nodeID", info.NodeID).WithField("func", "OnNodeNotReady") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err == nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // delete node from api server | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.Info("DeleteBaseNode") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| deleteErr := k8sClient.Delete(ctx, &node) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if deleteErr != nil && !apiErrors.IsNotFound(err) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.WithError(deleteErr).Info("delete base node failed") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if apiErrors.IsNotFound(err) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.Info("Node not found, skipping delete operation") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.WithError(err).Error("Failed to get node, cannot delete") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+215
to
+233
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add retry mechanism for transient errors While the error handling is good, consider adding a retry mechanism for transient errors when getting the node: func OnBaseUnreachable(ctx context.Context, info vkModel.UnreachableNodeInfo, env string, k8sClient client.Client) {
node := corev1.Node{}
nodeName := utils.FormatNodeName(info.NodeID, env)
- err := k8sClient.Get(ctx, client.ObjectKey{Name: nodeName}, &node)
logger := log.G(ctx).WithField("nodeID", info.NodeID).WithField("func", "OnNodeNotReady")
+
+ var err error
+ maxRetries := 3
+ for i := 0; i < maxRetries; i++ {
+ err = k8sClient.Get(ctx, client.ObjectKey{Name: nodeName}, &node)
+ if err == nil || apiErrors.IsNotFound(err) {
+ break
+ }
+ logger.WithError(err).WithField("retry", i+1).Error("Failed to get node")
+ time.Sleep(time.Duration(i+1) * time.Second)
+ }
+
if err == nil {
// delete node from api server
logger.Info("DeleteBaseNode")
deleteErr := k8sClient.Delete(ctx, &node)
if deleteErr != nil && !apiErrors.IsNotFound(err) {
logger.WithError(deleteErr).Info("delete base node failed")
}
} else if apiErrors.IsNotFound(err) {
logger.Info("Node not found, skipping delete operation")
} else {
logger.WithError(err).Error("Failed to get node, cannot delete")
}
}📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Check: codecov/patch
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func ExtractNetworkInfoFromNodeInfoData(initData vkModel.NodeInfo) model.NetworkInfo { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| portStr := initData.CustomLabels[model.LabelKeyOfArkletPort] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| port, err := strconv.Atoi(portStr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logrus.Errorf("failed to parse port %s from node info", portStr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| port = 1238 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return model.NetworkInfo{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| LocalIP: initData.NetworkInfo.NodeIP, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| LocalHostName: initData.NetworkInfo.HostName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ArkletPort: port, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+235
to
+249
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve network info extraction robustness Several improvements can be made to make this function more robust: +const (
+ DefaultArkletPort = 1238
+ MinPort = 1
+ MaxPort = 65535
+)
+
func ExtractNetworkInfoFromNodeInfoData(initData vkModel.NodeInfo) model.NetworkInfo {
portStr := initData.CustomLabels[model.LabelKeyOfArkletPort]
port, err := strconv.Atoi(portStr)
if err != nil {
logrus.Errorf("failed to parse port %s from node info", portStr)
- port = 1238
+ port = DefaultArkletPort
+ } else if port < MinPort || port > MaxPort {
+ logrus.Warnf("port %d out of valid range, using default", port)
+ port = DefaultArkletPort
}
+ if initData.NetworkInfo.NodeIP == "" {
+ logrus.Warn("empty NodeIP in node info")
+ }
+ if initData.NetworkInfo.HostName == "" {
+ logrus.Warn("empty HostName in node info")
+ }
+
return model.NetworkInfo{
LocalIP: initData.NetworkInfo.NodeIP,
LocalHostName: initData.NetworkInfo.HostName,
ArkletPort: port,
}
}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,23 +7,13 @@ metadata: | |
| spec: | ||
| containers: | ||
| - name: base | ||
| image: serverless-registry.cn-shanghai.cr.aliyuncs.com/opensource/test/base-web:latest # 已经打包好的镜像 | ||
| image: serverless-registry.cn-shanghai.cr.aliyuncs.com/opensource/test/base-web:1.1.1 # 已经打包好的镜像 | ||
| imagePullPolicy: Always | ||
| ports: | ||
| - name: base | ||
| containerPort: 8080 | ||
| - name: arklet | ||
| containerPort: 1238 | ||
|
Comment on lines
+15
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Port 1238 needs to be exposed through a Service definition The verification reveals that while port 1238 is defined in the Pod spec for the arklet container, there is no corresponding Service definition to expose this port. If this port needs to be accessible by other components in the cluster, you should:
🔗 Analysis chainVerify service exposure for arklet port While the arklet port is correctly configured in the Pod spec, ensure that this port is properly exposed through a Kubernetes Service if it needs to be accessible by other components. The previous search might have been too specific. Let's broaden our search to find Service definitions and any arklet-related configurations to verify if the port needs to be exposed through a Service. 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Check if there's a corresponding Service definition for the arklet port
rg -t yaml "ports.*name:\s*arklet"
Length of output: 36 Script: #!/bin/bash
# Let's search more broadly for service definitions and ports in yaml files
fd -e yaml -x cat {} | grep -A 10 -B 2 "kind:\s*Service"
# Also search for any arklet related configurations
rg -t yaml "arklet" -C 5
Length of output: 1765 |
||
| env: | ||
| - name: KUPLELESS_ARKLET_MQTT_BROKER | ||
| value: 10.244.0.27 | ||
| - name: KUPLELESS_ARKLET_MQTT_PORT | ||
| value: "1883" | ||
| - name: KUPLELESS_ARKLET_MQTT_USERNAME | ||
| value: koupleless_base | ||
| - name: KUPLELESS_ARKLET_MQTT_PASSWORD | ||
| value: public | ||
| - name: KUPLELESS_ARKLET_MQTT_CLIENT_PREFIX | ||
| value: koupleless | ||
| - name: KUPLELESS_ARKLET_CUSTOM_TUNNEL_CLASSNAME | ||
| value: com.alipay.sofa.koupleless.arklet.tunnel.mqtt.MqttTunnel | ||
| - name: KUPLELESS_ARKLET_CUSTOM_BASE_METADATA_CLASSNAME | ||
| value: com.alipay.sofa.web.base.metadata.MetadataHook | ||
| - name: MODULE_CONTROLLER_ADDRESS | ||
| value: {YOUR_MODULE_CONTROLLER_IP} | ||
|
Comment on lines
+18
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace hardcoded placeholder with proper K8s configuration The
Example improvement using ConfigMap: apiVersion: v1
kind: ConfigMap
metadata:
name: module-controller-config
data:
address: "your-module-controller-service"
---
# In the Pod spec:
env:
- name: MODULE_CONTROLLER_ADDRESS
valueFrom:
configMapKeyRef:
name: module-controller-config
key: address🧰 Tools🪛 yamllint
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Refactor Environment Variable Parsing into Utility Function
The code for parsing integer environment variables and handling errors is repeated for
WORKLOAD_MAX_LEVELandVNODE_WORKER_NUM. Consider refactoring this logic into a utility function to reduce code duplication and improve maintainability.Example utility function in the
utilspackage:Update the code to use the utility function: