Просмотр исходного кода

POR-2123: support job run on cli (#3989)

d-g-town 2 лет назад
Родитель
Сommit
7fbba9a2f4
4 измененных файлов с 96 добавлено и 5 удалено
  1. 3 3
      api/client/api.go
  2. 27 0
      api/client/porter_app.go
  3. 27 2
      cli/cmd/commands/app.go
  4. 39 0
      cli/cmd/v2/run_job.go

+ 3 - 3
api/client/api.go

@@ -166,7 +166,7 @@ func (c *Client) postRequest(relPath string, data interface{}, response interfac
 	}
 	}
 
 
 	var httpErr *types.ExternalError
 	var httpErr *types.ExternalError
-	var err error
+	var sendErr error
 
 
 	for i := 0; i < int(retryCount); i++ {
 	for i := 0; i < int(retryCount); i++ {
 		strData, err := json.Marshal(data)
 		strData, err := json.Marshal(data)
@@ -184,10 +184,10 @@ func (c *Client) postRequest(relPath string, data interface{}, response interfac
 		}
 		}
 
 
 		httpErr, err = c.sendRequest(req, response, true)
 		httpErr, err = c.sendRequest(req, response, true)
-
 		if httpErr == nil && err == nil {
 		if httpErr == nil && err == nil {
 			return nil
 			return nil
 		}
 		}
+		sendErr = err
 
 
 		if i != int(retryCount)-1 {
 		if i != int(retryCount)-1 {
 			if httpErr != nil {
 			if httpErr != nil {
@@ -202,7 +202,7 @@ func (c *Client) postRequest(relPath string, data interface{}, response interfac
 		return fmt.Errorf("%v", httpErr.Error)
 		return fmt.Errorf("%v", httpErr.Error)
 	}
 	}
 
 
-	return err
+	return sendErr
 }
 }
 
 
 type patchRequestOpts struct {
 type patchRequestOpts struct {

+ 27 - 0
api/client/porter_app.go

@@ -724,3 +724,30 @@ func (c *Client) UseNewApplyLogic(
 
 
 	return resp, err
 	return resp, err
 }
 }
+
+// RunAppJob runs a job for an app
+func (c *Client) RunAppJob(
+	ctx context.Context,
+	projectID, clusterID uint,
+	appName string, jobName string,
+	deploymentTargetID string,
+) (*porter_app.AppRunResponse, error) {
+	resp := &porter_app.AppRunResponse{}
+
+	req := &porter_app.AppRunRequest{
+		ServiceName:        jobName,
+		DeploymentTargetID: deploymentTargetID,
+	}
+
+	err := c.postRequest(
+		fmt.Sprintf(
+			"/projects/%d/clusters/%d/apps/%s/run",
+			projectID, clusterID,
+			appName,
+		),
+		req,
+		resp,
+	)
+
+	return resp, err
+}

+ 27 - 2
cli/cmd/commands/app.go

@@ -42,6 +42,7 @@ var (
 	appTag           string
 	appTag           string
 	appCpuMilli      int
 	appCpuMilli      int
 	appMemoryMi      int
 	appMemoryMi      int
+	jobName          string
 )
 )
 
 
 const (
 const (
@@ -60,7 +61,7 @@ func registerCommand_App(cliConf config.CLIConfig) *cobra.Command {
 	// appRunCmd represents the "porter app run" subcommand
 	// appRunCmd represents the "porter app run" subcommand
 	appRunCmd := &cobra.Command{
 	appRunCmd := &cobra.Command{
 		Use:   "run [application] -- COMMAND [args...]",
 		Use:   "run [application] -- COMMAND [args...]",
-		Args:  cobra.MinimumNArgs(2),
+		Args:  cobra.MinimumNArgs(1),
 		Short: "Runs a command inside a connected cluster container.",
 		Short: "Runs a command inside a connected cluster container.",
 		Run: func(cmd *cobra.Command, args []string) {
 		Run: func(cmd *cobra.Command, args []string) {
 			err := checkLoginAndRunWithConfig(cmd, cliConf, args, appRun)
 			err := checkLoginAndRunWithConfig(cmd, cliConf, args, appRun)
@@ -169,6 +170,13 @@ func appRunFlags(appRunCmd *cobra.Command) {
 		"",
 		"",
 		"name of the container inside pod to run the command in",
 		"name of the container inside pod to run the command in",
 	)
 	)
+
+	appRunCmd.PersistentFlags().StringVar(
+		&jobName,
+		"job",
+		"",
+		"name of the job to run (will run the job as defined instead of the provided command, and returns the job run id without waiting for the job to complete or displaying logs)",
+	)
 }
 }
 
 
 func appRollback(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client api.Client, cliConfig config.CLIConfig, _ config.FeatureFlags, _ *cobra.Command, args []string) error {
 func appRollback(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client api.Client, cliConfig config.CLIConfig, _ config.FeatureFlags, _ *cobra.Command, args []string) error {
@@ -198,7 +206,24 @@ func appRollback(ctx context.Context, _ *types.GetAuthenticatedUserResponse, cli
 	return nil
 	return nil
 }
 }
 
 
-func appRun(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client api.Client, cliConfig config.CLIConfig, _ config.FeatureFlags, _ *cobra.Command, args []string) error {
+func appRun(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client api.Client, cliConfig config.CLIConfig, ff config.FeatureFlags, _ *cobra.Command, args []string) error {
+	if jobName != "" {
+		if !ff.ValidateApplyV2Enabled {
+			return fmt.Errorf("job flag is not supported on this project")
+		}
+
+		return v2.RunAppJob(ctx, v2.RunAppJobInput{
+			CLIConfig: cliConfig,
+			Client:    client,
+			AppName:   args[0],
+			JobName:   jobName,
+		})
+	}
+
+	if len(args) < 2 {
+		return fmt.Errorf("porter app run requires at least 2 arguments")
+	}
+
 	execArgs := args[1:]
 	execArgs := args[1:]
 
 
 	color.New(color.FgGreen).Println("Attempting to run", strings.Join(execArgs, " "), "for application", args[0])
 	color.New(color.FgGreen).Println("Attempting to run", strings.Join(execArgs, " "), "for application", args[0])

+ 39 - 0
cli/cmd/v2/run_job.go

@@ -0,0 +1,39 @@
+package v2
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/fatih/color"
+
+	api "github.com/porter-dev/porter/api/client"
+	"github.com/porter-dev/porter/cli/cmd/config"
+)
+
+// RunAppJobInput is the input for the RunAppJob function
+type RunAppJobInput struct {
+	// CLIConfig is the CLI configuration
+	CLIConfig config.CLIConfig
+	// Client is the Porter API client
+	Client api.Client
+
+	AppName string
+	JobName string
+}
+
+// RunAppJob triggers a job run for an app and returns without waiting for the job to complete
+func RunAppJob(ctx context.Context, inp RunAppJobInput) error {
+	targetResp, err := inp.Client.DefaultDeploymentTarget(ctx, inp.CLIConfig.Project, inp.CLIConfig.Cluster)
+	if err != nil {
+		return fmt.Errorf("error calling default deployment target endpoint: %w", err)
+	}
+
+	resp, err := inp.Client.RunAppJob(ctx, inp.CLIConfig.Project, inp.CLIConfig.Cluster, inp.AppName, inp.JobName, targetResp.DeploymentTargetID)
+	if err != nil {
+		return fmt.Errorf("unable to run job: %w", err)
+	}
+
+	color.New(color.FgGreen).Println("Triggered job with id:", resp.JobRunID) // nolint:errcheck,gosec
+
+	return nil
+}