Wait for expected pod status on `compose up`

Signed-off-by: aiordache <anca.iordache@docker.com>
This commit is contained in:
aiordache 2021-02-19 20:10:28 +01:00
parent 03bce03028
commit 9ec5af76cd
3 changed files with 117 additions and 12 deletions

View File

@ -22,6 +22,7 @@ import (
"context"
"fmt"
"io"
"time"
"github.com/docker/compose-cli/api/compose"
"github.com/docker/compose-cli/utils"
@ -83,16 +84,6 @@ func (kc KubeClient) GetContainers(ctx context.Context, projectName string, all
return result, nil
}
func podToContainerSummary(pod corev1.Pod) compose.ContainerSummary {
return compose.ContainerSummary{
ID: pod.GetObjectMeta().GetName(),
Name: pod.GetObjectMeta().GetName(),
Service: pod.GetObjectMeta().GetLabels()[compose.ServiceTag],
State: string(pod.Status.Phase),
Project: pod.GetObjectMeta().GetLabels()[compose.ProjectTag],
}
}
// GetLogs retrieves pod logs
func (kc *KubeClient) GetLogs(ctx context.Context, projectName string, consumer compose.LogConsumer, follow bool) error {
pods, err := kc.client.CoreV1().Pods(kc.namespace).List(ctx, metav1.ListOptions{
@ -111,13 +102,81 @@ func (kc *KubeClient) GetLogs(ctx context.Context, projectName string, consumer
eg.Go(func() error {
r, err := request.Stream(ctx)
defer r.Close() // nolint errcheck
if err != nil {
return err
}
defer r.Close() // nolint errcheck
_, err = io.Copy(w, r)
return err
})
}
return eg.Wait()
}
// WaitForRunningPodState blocks until pods are in running state
func (kc KubeClient) WaitForPodState(ctx context.Context, projectName string, services []string, status string, timeout int) error {
if timeout > 0 {
var t time.Duration
t = time.Duration(timeout) * time.Second
fmt.Println("Timeout ", t)
}
selector := fmt.Sprintf("%s=%s", compose.ProjectTag, projectName)
waitingForPhase := corev1.PodRunning
switch status {
case compose.STARTING:
waitingForPhase = corev1.PodPending
case compose.UNKNOWN:
waitingForPhase = corev1.PodUnknown
}
//fieldSelector := "status.phase=Running"
for {
time.Sleep(time.Duration(1) * time.Second)
timeout = timeout - 1
if timeout <= 0 {
return fmt.Errorf("Deployment time out. Pods did not reach expected state.")
}
pods, err := kc.client.CoreV1().Pods(kc.namespace).List(ctx, metav1.ListOptions{
LabelSelector: selector,
})
if err != nil {
return err
}
servicePods := 0
stateReached := true
for _, pod := range pods.Items {
if status == compose.REMOVING {
if contains(services, pod.Labels[compose.ServiceTag]) {
servicePods = servicePods + 1
}
continue
}
if pod.Status.Phase != waitingForPhase {
stateReached = false
}
}
if status == compose.REMOVING {
if len(pods.Items) > 0 {
continue
}
return nil
}
if !stateReached {
continue
}
return nil
}
}

43
kube/client/utils.go Normal file
View File

@ -0,0 +1,43 @@
// +build kube
/*
Copyright 2020 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package client
import (
"github.com/docker/compose-cli/api/compose"
corev1 "k8s.io/api/core/v1"
)
func podToContainerSummary(pod corev1.Pod) compose.ContainerSummary {
return compose.ContainerSummary{
ID: pod.GetObjectMeta().GetName(),
Name: pod.GetObjectMeta().GetName(),
Service: pod.GetObjectMeta().GetLabels()[compose.ServiceTag],
State: string(pod.Status.Phase),
Project: pod.GetObjectMeta().GetLabels()[compose.ProjectTag],
}
}
func contains(slice []string, item string) bool {
for _, v := range slice {
if v == item {
return true
}
}
return false
}

View File

@ -91,7 +91,10 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
})
w.Event(progress.NewEvent(eventName, progress.Done, ""))
return err
eventName = "Wait for pods to be running"
return s.client.WaitForPodState(ctx, project.Name, project.ServiceNames(), compose.RUNNING, 10)
}
// Down executes the equivalent to a `compose down`