github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/cmd/jobs.go (about)

     1  package cmd
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"net/url"
     9  	"os"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/cozy/cozy-stack/client"
    14  	"github.com/cozy/cozy-stack/client/request"
    15  
    16  	"github.com/spf13/cobra"
    17  )
    18  
    19  var flagJobJSONArg string
    20  var flagJobPrintLogs bool
    21  var flagJobPrintLogsVerbose bool
    22  var flagJobWorkers []string
    23  var flagJobsPurgeDuration string
    24  
    25  var jobsCmdGroup = &cobra.Command{
    26  	Use:   "jobs <command>",
    27  	Short: "Launch and manage jobs and workers",
    28  }
    29  
    30  var jobsRunCmd = &cobra.Command{
    31  	Use:     "run <worker>",
    32  	Aliases: []string{"launch", "push"},
    33  	Example: `$ cozy-stack jobs run service --domain example.mycozy.cloud --json '{"slug": "banks", "name": "onOperationOrBillCreate", "file": "onOperationOrBillCreate.js"}'`,
    34  	RunE: func(cmd *cobra.Command, args []string) error {
    35  		if len(args) < 1 {
    36  			return cmd.Help()
    37  		}
    38  		if flagDomain == "" {
    39  			return errMissingDomain
    40  		}
    41  		if flagJobJSONArg == "" {
    42  			return errors.New("The JSON argument is missing")
    43  		}
    44  		c := newClient(flagDomain, "io.cozy.jobs", "io.cozy.jobs.logs")
    45  		o := &client.JobOptions{
    46  			Worker:    args[0],
    47  			Arguments: json.RawMessage(flagJobJSONArg),
    48  		}
    49  		if flagJobPrintLogs {
    50  			o.Logs = make(chan *client.JobLog)
    51  			go func() {
    52  				for log := range o.Logs {
    53  					fmt.Fprintf(os.Stdout, "[%s]", log.Level)
    54  					if flagJobPrintLogsVerbose {
    55  						fmt.Fprintf(os.Stdout, "[time:%s]", log.Time.Format(time.RFC3339))
    56  						for k, v := range log.Data {
    57  							fmt.Fprintf(os.Stdout, "[%s:%s]", k, v)
    58  						}
    59  					}
    60  					fmt.Fprintf(os.Stdout, " %s\n", log.Message)
    61  				}
    62  			}()
    63  		}
    64  		j, err := c.JobPush(o)
    65  		if err != nil {
    66  			return err
    67  		}
    68  		b, err := json.MarshalIndent(j, "", "  ")
    69  		if err != nil {
    70  			return err
    71  		}
    72  		fmt.Println(string(b))
    73  		return nil
    74  	},
    75  }
    76  
    77  var jobsPurgeCmd = &cobra.Command{
    78  	Use:     "purge-old-jobs <domain>",
    79  	Short:   `Purge old jobs from an instance`,
    80  	Example: `$ cozy-stack jobs purge-old-jobs example.mycozy.cloud`,
    81  	RunE: func(cmd *cobra.Command, args []string) error {
    82  		if len(args) != 1 {
    83  			return cmd.Help()
    84  		}
    85  
    86  		var workers string
    87  		if flagJobWorkers != nil {
    88  			workers = strings.Join(flagJobWorkers, ",")
    89  		}
    90  		duration := flagJobsPurgeDuration
    91  
    92  		q := url.Values{
    93  			"duration": {duration},
    94  			"workers":  {workers},
    95  		}
    96  		c := newClient(args[0], "io.cozy.jobs:DELETE")
    97  
    98  		res, err := c.Req(&request.Options{
    99  			Method:  "DELETE",
   100  			Path:    "/jobs/purge",
   101  			Queries: q,
   102  		})
   103  
   104  		if err != nil {
   105  			return err
   106  		}
   107  
   108  		resContent, err := io.ReadAll(res.Body)
   109  		if err != nil {
   110  			return err
   111  		}
   112  		fmt.Println(string(resContent))
   113  		return nil
   114  	},
   115  }
   116  
   117  func init() {
   118  	jobsCmdGroup.PersistentFlags().StringVar(&flagDomain, "domain", cozyDomain(), "specify the domain name of the instance")
   119  
   120  	jobsRunCmd.Flags().StringVar(&flagJobJSONArg, "json", "", "specify the job arguments as raw JSON")
   121  	jobsRunCmd.Flags().BoolVar(&flagJobPrintLogs, "logs", false, "print jobs log in stdout")
   122  	jobsRunCmd.Flags().BoolVar(&flagJobPrintLogsVerbose, "logs-verbose", false, "verbose logging (with --logs flag)")
   123  
   124  	jobsPurgeCmd.Flags().StringSliceVar(&flagJobWorkers, "workers", nil, "worker types to iterate over (all workers by default)")
   125  	jobsPurgeCmd.Flags().StringVar(&flagJobsPurgeDuration, "duration", "", "duration to look for (ie. 3D, 2M)")
   126  
   127  	jobsCmdGroup.AddCommand(jobsRunCmd)
   128  	jobsCmdGroup.AddCommand(jobsPurgeCmd)
   129  	RootCmd.AddCommand(jobsCmdGroup)
   130  }