180 lines
3.7 KiB
Markdown
180 lines
3.7 KiB
Markdown
# Job Format
|
|
|
|
Jobs are the fundamental unit of work in Horus.
|
|
|
|
## Structure
|
|
|
|
```rust
|
|
pub struct Job {
|
|
pub id: String, // Unique job identifier
|
|
pub runner_id: String, // Target runner ID
|
|
pub payload: String, // Job payload (script/command)
|
|
pub timeout: Option<u64>, // Timeout in seconds
|
|
pub env_vars: HashMap<String, String>, // Environment variables
|
|
pub signatures: Vec<Signature>, // Cryptographic signatures
|
|
pub created_at: i64, // Creation timestamp
|
|
pub status: JobStatus, // Current status
|
|
}
|
|
```
|
|
|
|
## Job Status
|
|
|
|
```rust
|
|
pub enum JobStatus {
|
|
Pending, // Queued, not yet started
|
|
Running, // Currently executing
|
|
Completed, // Finished successfully
|
|
Failed, // Execution failed
|
|
Timeout, // Exceeded timeout
|
|
Cancelled, // Manually cancelled
|
|
}
|
|
```
|
|
|
|
## Signature Format
|
|
|
|
```rust
|
|
pub struct Signature {
|
|
pub public_key: String, // Signer's public key
|
|
pub signature: String, // Cryptographic signature
|
|
pub algorithm: String, // Signature algorithm (e.g., "ed25519")
|
|
}
|
|
```
|
|
|
|
## Creating a Job
|
|
|
|
### Minimal Job
|
|
|
|
```rust
|
|
use hero_job::Job;
|
|
|
|
let job = Job::new(
|
|
"my-runner",
|
|
"print('Hello World')".to_string(),
|
|
);
|
|
```
|
|
|
|
### With Timeout
|
|
|
|
```rust
|
|
let job = Job::builder()
|
|
.runner_id("my-runner")
|
|
.payload("long_running_task()")
|
|
.timeout(300) // 5 minutes
|
|
.build();
|
|
```
|
|
|
|
### With Environment Variables
|
|
|
|
```rust
|
|
use std::collections::HashMap;
|
|
|
|
let mut env_vars = HashMap::new();
|
|
env_vars.insert("API_KEY".to_string(), "secret".to_string());
|
|
env_vars.insert("ENV".to_string(), "production".to_string());
|
|
|
|
let job = Job::builder()
|
|
.runner_id("my-runner")
|
|
.payload("deploy_app()")
|
|
.env_vars(env_vars)
|
|
.build();
|
|
```
|
|
|
|
### With Signature
|
|
|
|
```rust
|
|
use hero_job::{Job, Signature};
|
|
|
|
let job = Job::builder()
|
|
.runner_id("my-runner")
|
|
.payload("important_task()")
|
|
.signature(Signature {
|
|
public_key: "ed25519:abc123...".to_string(),
|
|
signature: "sig:xyz789...".to_string(),
|
|
algorithm: "ed25519".to_string(),
|
|
})
|
|
.build();
|
|
```
|
|
|
|
## Payload Format
|
|
|
|
The payload format depends on the target runner:
|
|
|
|
### Hero Runner
|
|
Heroscript content:
|
|
```heroscript
|
|
!!git.list
|
|
print("Repositories listed")
|
|
!!docker.ps
|
|
```
|
|
|
|
### SAL Runner
|
|
Rhai script with SAL modules:
|
|
```rhai
|
|
let files = os.list_dir("/tmp");
|
|
for file in files {
|
|
print(file);
|
|
}
|
|
```
|
|
|
|
### Osiris Runner
|
|
Rhai script with Osiris database:
|
|
```rhai
|
|
let users = osiris.model("users");
|
|
let user = users.create(#{
|
|
name: "Alice",
|
|
email: "alice@example.com"
|
|
});
|
|
```
|
|
|
|
## Job Result
|
|
|
|
```rust
|
|
pub struct JobResult {
|
|
pub job_id: String,
|
|
pub status: JobStatus,
|
|
pub output: String, // Stdout
|
|
pub error: Option<String>, // Stderr or error message
|
|
pub exit_code: Option<i32>,
|
|
pub started_at: Option<i64>,
|
|
pub completed_at: Option<i64>,
|
|
}
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### Timeouts
|
|
- Always set timeouts for jobs
|
|
- Default: 60 seconds
|
|
- Long-running jobs: Set appropriate timeout
|
|
- Infinite jobs: Use separate monitoring
|
|
|
|
### Environment Variables
|
|
- Don't store secrets in env vars in production
|
|
- Use vault/secret management instead
|
|
- Keep env vars minimal
|
|
- Document required variables
|
|
|
|
### Signatures
|
|
- Always sign jobs in production
|
|
- Use strong algorithms (ed25519)
|
|
- Rotate keys regularly
|
|
- Store private keys securely
|
|
|
|
### Payloads
|
|
- Keep payloads concise
|
|
- Validate input data
|
|
- Handle errors gracefully
|
|
- Log important operations
|
|
|
|
## Validation
|
|
|
|
Jobs are validated before execution:
|
|
|
|
1. **Structure**: All required fields present
|
|
2. **Signature**: Valid cryptographic signature
|
|
3. **Runner**: Target runner exists and available
|
|
4. **Payload**: Non-empty payload
|
|
5. **Timeout**: Reasonable timeout value
|
|
|
|
Invalid jobs are rejected before execution.
|