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 }