This repository has been archived by the owner on Apr 2, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding schedule command to schedule cron jobs.
Adding example of a cron job. Removing functions since they've been moved elsewhere.
- Loading branch information
Showing
9 changed files
with
428 additions
and
278 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* 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 cmd | ||
|
||
import ( | ||
"github.com/aurora-scheduler/australis/internal" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func init() { | ||
rootCmd.AddCommand(scheduleCmd) | ||
|
||
} | ||
|
||
var scheduleCmd = &cobra.Command{ | ||
Use: "schedule", | ||
Short: "Schedule a cron job on Aurora scheduler", | ||
Run: scheduleCron, | ||
Args: cobra.ExactArgs(1), | ||
} | ||
|
||
func scheduleCron(cmd *cobra.Command, args []string) { | ||
job, err := internal.UnmarshalJob(args[0]) | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
|
||
if err := job.ValidateCron(); err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
auroraJob, err := job.ToRealis() | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
|
||
if err := client.ScheduleCronJob(auroraJob); err != nil { | ||
log.Fatal("unable to schedule job: ", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
## australis schedule | ||
|
||
Schedule a cron job on Aurora scheduler | ||
|
||
### Synopsis | ||
|
||
Schedule a cron job on Aurora scheduler | ||
|
||
``` | ||
australis schedule [flags] | ||
``` | ||
|
||
### Options | ||
|
||
``` | ||
-h, --help help for schedule | ||
``` | ||
|
||
### Options inherited from parent commands | ||
|
||
``` | ||
-a, --caCertsPath string Path where CA certificates can be found. | ||
-c, --clientCert string Client certificate to use to connect to Aurora. | ||
-k, --clientKey string Client key to use to connect to Aurora. | ||
--config string Config file to use. (default "/etc/aurora/australis.yml") | ||
-l, --logLevel string Set logging level [panic fatal error warning info debug trace]. (default "info") | ||
-p, --password string Password to use for API authentication | ||
-s, --scheduler_addr string Aurora Scheduler's address. | ||
-i, --skipCertVerification Skip CA certificate hostname verification. | ||
--toJSON Print output in JSON format. | ||
-u, --username string Username to use for API authentication | ||
-z, --zookeeper string Zookeeper node(s) where Aurora stores information. (comma separated list) | ||
``` | ||
|
||
### SEE ALSO | ||
|
||
* [australis](australis.md) - australis is a client for Apache Aurora | ||
|
||
###### Auto generated by spf13/cobra on 7-May-2020 |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
/** | ||
* 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 internal | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
|
||
realis "github.com/aurora-scheduler/gorealis/v2" | ||
"github.com/aurora-scheduler/gorealis/v2/gen-go/apache/aurora" | ||
) | ||
|
||
type URI struct { | ||
URI string `yaml:"uri"` | ||
Extract bool `yaml:"extract"` | ||
Cache bool `yaml:"cache"` | ||
} | ||
|
||
type Executor struct { | ||
Name string `yaml:"name"` | ||
Data string `yaml:"data"` | ||
} | ||
|
||
type ThermosProcess struct { | ||
Name string `yaml:"name"` | ||
Cmd string `yaml:"cmd"` | ||
} | ||
|
||
type DockerContainer struct { | ||
Name string `yaml:"name"` | ||
Tag string `yaml:"tag"` | ||
} | ||
|
||
type Container struct { | ||
Docker *DockerContainer `yaml:"docker"` | ||
} | ||
|
||
type Job struct { | ||
Environment string `yaml:"environment"` | ||
Role string `yaml:"role"` | ||
Name string `yaml:"name"` | ||
CPU float64 `yaml:"cpu"` | ||
RAM int64 `yaml:"ram"` | ||
Disk int64 `yaml:"disk"` | ||
Executor Executor `yaml:"executor"` | ||
Instances int32 `yaml:"instances"` | ||
MaxFailures int32 `yaml:"maxFailures"` | ||
URIs []URI `yaml:"uris"` | ||
Metadata map[string]string `yaml:"labels"` | ||
Service bool `yaml:"service"` | ||
Thermos []ThermosProcess `yaml:",flow,omitempty"` | ||
Container *Container `yaml:"container,omitempty"` | ||
CronSchedule *string `yaml:"cronSchedule,omitempty"` | ||
CronCollisionPolicy *string `yaml:"cronCollisionPolicy,omitempty"` | ||
} | ||
|
||
func (j *Job) ToRealis() (*realis.AuroraJob, error) { | ||
auroraJob := realis.NewJob(). | ||
Environment(j.Environment). | ||
Role(j.Role). | ||
Name(j.Name). | ||
CPU(j.CPU). | ||
RAM(j.RAM). | ||
Disk(j.Disk). | ||
IsService(j.Service). | ||
InstanceCount(j.Instances). | ||
MaxFailure(j.MaxFailures) | ||
|
||
if j.CronSchedule != nil { | ||
auroraJob.CronSchedule(*j.CronSchedule) | ||
} | ||
|
||
if j.CronCollisionPolicy != nil { | ||
// Ignoring error because we have already checked for it in the validate function | ||
policy, _ := aurora.CronCollisionPolicyFromString(*j.CronCollisionPolicy) | ||
auroraJob.CronCollisionPolicy(policy) | ||
} | ||
|
||
// Adding URIs. | ||
for _, uri := range j.URIs { | ||
auroraJob.AddURIs(uri.Extract, uri.Cache, uri.URI) | ||
} | ||
|
||
// Adding Metadata. | ||
for key, value := range j.Metadata { | ||
auroraJob.AddLabel(key, value) | ||
} | ||
|
||
// If thermos jobs processes are provided, use them | ||
if len(j.Thermos) > 0 { | ||
thermosExec := realis.ThermosExecutor{} | ||
for _, process := range j.Thermos { | ||
thermosExec.AddProcess(realis.NewThermosProcess(process.Name, process.Cmd)) | ||
} | ||
auroraJob.ThermosExecutor(thermosExec) | ||
} else if j.Executor.Name != "" { | ||
// Non-Thermos executor | ||
if j.Executor.Name == "" { | ||
return nil, errors.New("no executor name provided") | ||
} | ||
|
||
auroraJob.ExecutorName(j.Executor.Name) | ||
auroraJob.ExecutorData(j.Executor.Data) | ||
} else if j.Container != nil { | ||
if j.Container.Docker == nil { | ||
return nil, errors.New("no container specified") | ||
} | ||
|
||
if j.Container.Docker.Tag != "" && !strings.ContainsRune(j.Container.Docker.Name, ':') { | ||
j.Container.Docker.Name += ":" + j.Container.Docker.Tag | ||
} | ||
auroraJob.Container(realis.NewDockerContainer().Image(j.Container.Docker.Name)) | ||
|
||
} | ||
|
||
return auroraJob, nil | ||
} | ||
|
||
func (j *Job) Validate() error { | ||
if j.Name == "" { | ||
return errors.New("job name not specified") | ||
} | ||
|
||
if j.Role == "" { | ||
return errors.New("job role not specified") | ||
} | ||
|
||
if j.Environment == "" { | ||
return errors.New("job environment not specified") | ||
} | ||
|
||
if j.Instances <= 0 { | ||
return errors.New("number of instances in job cannot be less than or equal to 0") | ||
} | ||
|
||
if j.CPU <= 0.0 { | ||
return errors.New("CPU must be greater than 0") | ||
} | ||
|
||
if j.RAM <= 0 { | ||
return errors.New("RAM must be greater than 0") | ||
} | ||
|
||
if j.Disk <= 0 { | ||
return errors.New("disk must be greater than 0") | ||
} | ||
|
||
if len(j.Thermos) == 0 && j.Executor.Name == "" && j.Container == nil { | ||
return errors.New("task does not contain a thermos definition, a custom executor name, or a container to launch") | ||
} | ||
return nil | ||
} | ||
func (j *Job) ValidateCron() error { | ||
if j.CronSchedule == nil { | ||
return errors.New("cron schedule must be set") | ||
} | ||
|
||
if j.CronCollisionPolicy != nil { | ||
if _, err := aurora.CronCollisionPolicyFromString(*j.CronCollisionPolicy); err != nil { | ||
return err | ||
} | ||
} else { | ||
killExisting := aurora.CronCollisionPolicy_KILL_EXISTING.String() | ||
j.CronCollisionPolicy = &killExisting | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.