From 52a59bbfee6cfaf9f256f3bcfd7abe88f80515e0 Mon Sep 17 00:00:00 2001
From: phantomjinx
Date: Tue, 27 Oct 2020 17:47:25 +0000
Subject: [PATCH] #1283: Enhance the `kamel log` command to show more detail
prior to install
* Sets up a polling prior to the complete install of an integration
* First report whether it finds the integration
* Assume it finds an integration then determine its status
* If it gets to Building Kit (which can take a while) then find the
associated IntegrationKit and report its status
* Finally return to the scraping of the log once the integration is up
and running
---
pkg/cmd/log.go | 125 ++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 119 insertions(+), 6 deletions(-)
diff --git a/pkg/cmd/log.go b/pkg/cmd/log.go
index f92ed98508..dc2f854359 100644
--- a/pkg/cmd/log.go
+++ b/pkg/cmd/log.go
@@ -19,11 +19,15 @@ package cmd
import (
"errors"
+ "fmt"
+ "time"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
k8slog "github.com/apache/camel-k/pkg/util/kubernetes/log"
"github.com/spf13/cobra"
+ k8errors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/util/wait"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -65,6 +69,9 @@ func (o *logCmdOptions) run(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
+
+ integrationId := args[0]
+
integration := v1.Integration{
TypeMeta: metav1.TypeMeta{
Kind: v1.IntegrationKind,
@@ -72,18 +79,124 @@ func (o *logCmdOptions) run(cmd *cobra.Command, args []string) error {
},
ObjectMeta: metav1.ObjectMeta{
Namespace: o.Namespace,
- Name: args[0],
+ Name: integrationId,
},
}
key := k8sclient.ObjectKey{
Namespace: o.Namespace,
- Name: args[0],
+ Name: integrationId,
}
- if err := c.Get(o.Context, key, &integration); err != nil {
- return err
- }
- if err := k8slog.Print(o.Context, c, &integration, cmd.OutOrStdout()); err != nil {
+ var pollTimeout = 600 * time.Second // 10 minutes should be adequate for a timeout
+ var pollInterval = 2 * time.Second
+ var currLogMsg = ""
+ var newLogMsg = ""
+
+ err = wait.PollImmediate(pollInterval, pollTimeout, func() (done bool, err error) {
+
+ //
+ // Reduce repetition of messages by tracking the last message
+ // and checking if its different from the new message
+ //
+ if newLogMsg != currLogMsg {
+ fmt.Println(newLogMsg)
+ currLogMsg = newLogMsg
+ }
+
+ //
+ // Try and find the integration
+ //
+ err = c.Get(o.Context, key, &integration)
+ if err != nil && !k8errors.IsNotFound(err) {
+ // different error so return
+ return false, err
+ }
+
+ if k8errors.IsNotFound(err) {
+ //
+ // Don't have an integration yet so log and wait
+ //
+ newLogMsg = fmt.Sprintf("Integration '%s' not yet available. Will keep checking ...", integrationId)
+ return false, nil
+ }
+
+ //
+ // Found the integration so check its status using its phase
+ //
+ phase := integration.Status.Phase
+ switch phase {
+ case "Running":
+ //
+ // Found the running integration so step over to scraping its pod log
+ //
+ fmt.Printf("Integration '%s' is now running. Showing log ...\n", integrationId)
+ if err := k8slog.Print(o.Context, c, &integration, cmd.OutOrStdout()); err != nil {
+ return false, err
+ } else {
+ return true, nil
+ }
+ break
+ case "Building Kit":
+ //
+ // This phase can take a while so check progress using
+ // the associated Integration Kit's progress
+ //
+ newLogMsg = fmt.Sprintf("The building kit for integration '%s' is being initialised. This may take some time ...", integrationId)
+ if integration.Status.Kit == "" {
+ //
+ // Not created yet so wait quietly
+ //
+ return false, nil
+ }
+
+ integrationKit := v1.IntegrationKit{
+ TypeMeta: metav1.TypeMeta{
+ Kind: v1.IntegrationKitKind,
+ APIVersion: v1.SchemeGroupVersion.String(),
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: o.Namespace,
+ Name: integration.Status.Kit,
+ },
+ }
+ ikKey := k8sclient.ObjectKey{
+ Namespace: o.Namespace,
+ Name: integration.Status.Kit,
+ }
+
+ //
+ // Query for the integration kit
+ //
+ if err := c.Get(o.Context, ikKey, &integrationKit); err != nil {
+ if !k8errors.IsNotFound(err) {
+ //
+ // Not created yet so wait quietly
+ //
+ return false, nil
+ } else {
+ //
+ // Integration kit query made an error
+ //
+ return false, err
+ }
+ }
+
+ //
+ // Found the building kit so output its phase
+ //
+ newLogMsg = fmt.Sprintf("The building kit for integration '%s' is at: %s", integrationId, integrationKit.Status.Phase)
+ break
+ default:
+ //
+ // Integration is still building, deploying or even in error
+ //
+ newLogMsg = fmt.Sprintf("Integration '%s' is at: %s ...", integrationId, phase)
+ }
+
+ return false, nil
+ })
+
+ if err != nil {
return err
}