|
|
@@ -4,14 +4,12 @@ import (
|
|
|
"context"
|
|
|
"fmt"
|
|
|
"os"
|
|
|
- "strconv"
|
|
|
- "time"
|
|
|
|
|
|
"github.com/fatih/color"
|
|
|
api "github.com/porter-dev/porter/api/client"
|
|
|
"github.com/porter-dev/porter/api/types"
|
|
|
+ "github.com/porter-dev/porter/cli/cmd/deploy/wait"
|
|
|
"github.com/spf13/cobra"
|
|
|
- v1 "k8s.io/api/batch/v1"
|
|
|
)
|
|
|
|
|
|
var jobCmd = &cobra.Command{
|
|
|
@@ -147,113 +145,10 @@ func batchImageUpdate(_ *types.GetAuthenticatedUserResponse, client *api.Client,
|
|
|
|
|
|
// waits for a job with a given name/namespace
|
|
|
func waitForJob(_ *types.GetAuthenticatedUserResponse, client *api.Client, args []string) error {
|
|
|
- // get the job release
|
|
|
- jobRelease, err := client.GetRelease(context.Background(), cliConf.Project, cliConf.Cluster, namespace, name)
|
|
|
-
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- // make sure the job chart has a manual job running
|
|
|
- pausedVal, ok := jobRelease.Release.Config["paused"]
|
|
|
- pausedErr := fmt.Errorf("this job template is not currently running a manual job")
|
|
|
-
|
|
|
- if !ok {
|
|
|
- return pausedErr
|
|
|
- }
|
|
|
-
|
|
|
- if pausedValBool, ok := pausedVal.(bool); ok && pausedValBool {
|
|
|
- return pausedErr
|
|
|
- }
|
|
|
-
|
|
|
- // attempt to parse out the timeout value for the job, given by `sidecar.timeout`
|
|
|
- // if it does not exist, we set the default to 30 minutes
|
|
|
- timeoutVal := GetJobTimeoutValue(jobRelease.Release.Config)
|
|
|
-
|
|
|
- color.New(color.FgYellow).Printf("Waiting for timeout seconds %.1f\n", timeoutVal.Seconds())
|
|
|
-
|
|
|
- // if no job exists with the given revision, wait for the timeout value
|
|
|
- timeWait := time.Now().Add(timeoutVal)
|
|
|
-
|
|
|
- for time.Now().Before(timeWait) {
|
|
|
- // get the jobs for that job chart
|
|
|
- jobs, err := client.GetJobs(context.Background(), cliConf.Project, cliConf.Cluster, namespace, name)
|
|
|
-
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- job := getJobMatchingRevision(uint(jobRelease.Release.Version), jobs)
|
|
|
-
|
|
|
- if job == nil {
|
|
|
- time.Sleep(10 * time.Second)
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- // once job is running, wait for status to be completed, or failed
|
|
|
- // if failed, exit with non-zero exit code
|
|
|
- if job.Status.Failed > 0 {
|
|
|
- return fmt.Errorf("job failed")
|
|
|
- }
|
|
|
-
|
|
|
- if job.Status.Succeeded > 0 {
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- // otherwise, return no error
|
|
|
- time.Sleep(10 * time.Second)
|
|
|
- }
|
|
|
-
|
|
|
- return fmt.Errorf("timed out waiting for job")
|
|
|
-}
|
|
|
-
|
|
|
-func getJobMatchingRevision(revision uint, jobs []v1.Job) *v1.Job {
|
|
|
- for _, job := range jobs {
|
|
|
- revisionLabel, revisionLabelExists := job.Labels["helm.sh/revision"]
|
|
|
-
|
|
|
- if !revisionLabelExists {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- jobRevision, err := strconv.ParseUint(revisionLabel, 10, 64)
|
|
|
-
|
|
|
- if err != nil {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- if uint(jobRevision) == revision {
|
|
|
- return &job
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func GetJobTimeoutValue(values map[string]interface{}) time.Duration {
|
|
|
- defaultTimeout := time.Minute * 60
|
|
|
- sidecarInter, ok := values["sidecar"]
|
|
|
-
|
|
|
- if !ok {
|
|
|
- return defaultTimeout
|
|
|
- }
|
|
|
-
|
|
|
- sidecarVal, ok := sidecarInter.(map[string]interface{})
|
|
|
-
|
|
|
- if !ok {
|
|
|
- return defaultTimeout
|
|
|
- }
|
|
|
-
|
|
|
- timeoutInter, ok := sidecarVal["timeout"]
|
|
|
-
|
|
|
- if !ok {
|
|
|
- return defaultTimeout
|
|
|
- }
|
|
|
-
|
|
|
- timeoutVal, ok := timeoutInter.(float64)
|
|
|
-
|
|
|
- if !ok {
|
|
|
- return defaultTimeout
|
|
|
- }
|
|
|
-
|
|
|
- return time.Second * time.Duration(timeoutVal)
|
|
|
+ return wait.WaitForJob(client, &wait.WaitOpts{
|
|
|
+ ProjectID: cliConf.Project,
|
|
|
+ ClusterID: cliConf.Cluster,
|
|
|
+ Namespace: namespace,
|
|
|
+ Name: name,
|
|
|
+ })
|
|
|
}
|