# Treadmill CLI
Treadmill CLI is a command-line interface tool for interacting with the Treadmill test bench system. It provides functionality for user authentication and job management.
## Features
- User authentication (login)
- Job management:
- Enqueue new jobs with various parameters
- List all jobs in the queue
- Check job status
- Cancel jobs
- SSH into a running job or device with an automatically generated key
- Configurable via command-line arguments or config file
## Installation
Ensure the CLI tool is in your system path or reference it directly using `./tml`.
## Usage
```
./tml [OPTIONS] <SUBCOMMAND>
```
### Global Options
- `-c, --config <FILE>`: Sets a custom config file
- `-u, --api-url <URL>`: Sets the API URL directly
- `-v, --verbose`: Enable verbose logging
### Subcommands
1. **Login**
```
./tml login
```
Or, optionally:
```
./tml login <USERNAME> [<PASSWORD>]
```
```
./tml login <USERNAME> <PASSWORD>
```
2. **Job Management**
- **Enqueue a job**:
```
./tml job enqueue <IMAGE_ID> [OPTIONS]
```
Options for job enqueue:
- `--ssh-keys <KEYS>`: Comma-separated list of SSH public keys
- `--restart-count <COUNT>`: Remaining restart count
- `--parameters <PARAMS>`: JSON object of job parameters
- `--tag-config <CONFIG>`: Tag configuration
- `--timeout <TIMEOUT>`: Override timeout in seconds
- **List all jobs**:
```
./tml job list
```
- **Check job status**:
```
./tml job status <JOB_ID>
```
- **Cancel a job**:
```
./tml job cancel <JOB_ID>
```
- **SSH into a running job**:
```
./tml job ssh <USER@IP>
```
- If you run `tml job ssh root@10.42.0.123`, the CLI will:
1. Check if a Treadmill-managed Ed25519 SSH key exists in `~/.local/share/treadmill-tb/ssh-key`.
2. If **no key** is found, automatically generate one and store it there with file permissions 0600.
3. Invoke `ssh -i ~/.local/share/treadmill-tb/ssh-key root@10.42.0.123`.
- If the key **already exists**, it reuses that key to connect.
## Login Options
Treadmill CLI allows you to log in using **several** different methods, **in order of precedence**:
1. **Positional Arguments**
- `<USERNAME> [<PASSWORD>]`
Examples:
```
./tml login ben mypassword
```
```
./tml login ben
```
In the second example, you’ll be prompted for the password.
2. **Environment Variables**
- `TML_USER`
- `TML_PASSWORD`
Example:
```
export TML_USER=ben
export TML_PASSWORD=supersecret
./tml login
```
If these environment variables are set, the CLI will use them **unless** the above command-line arguments override them.
3. **Interactive Prompt**
- If username and/or password aren’t provided by flags, positional arguments, or environment variables, the CLI will prompt you interactively.
### Examples
- **Fully Interactive**:
```
./tml login
```
- Prompts for username, then password.
- **Username Positional + Prompt for Password**:
```
./tml login ben
```
- Username is `ben`
- Prompts for password.
- **Username & Password Positional**:
```
./tml login ben mypassword
```
- Username is `ben`
- Password is `mypassword`
- No prompt needed.
- **Environment Variables**:
```
export TML_USER=ben
export TML_PASSWORD=supersecret
./tml login
```
- Username is `ben`
- Password is `supersecret`
- No prompt needed.
**Note**: The CLI always checks for **flags first**, **then** any **positional arguments**, **then** environment variables, **finally** falling back to prompts for whichever piece is still missing. This flexibility makes the CLI suitable for both interactive and CI-based automation.
## Configuration
The CLI can be configured using a TOML file. You can specify the config file path using the `-c` option.
Example configuration:
```toml
ssh_keys = "ssh-rsa AAAAB3NzaC1yc2E..., ssh-ed25519 AAAAC3NzaC1lZDI1NTE5..."
[api]
url = "https://swb.treadmill.ci"
```
## SSH Key Handling
The CLI reads SSH keys from multiple sources:
1. **SSH agent**
2. **Public key files** in the user's `.ssh` directory
3. **Config file** (as shown above)
If no SSH keys are provided via the command-line argument, the CLI will automatically attempt to read keys from these sources.
### Automatic Ed25519 Key Generation
When you run `tml job ssh <USER@IP>`, Treadmill CLI will:
- Check for an existing private key at `~/.local/share/treadmill-tb/ssh-key`.
- If not found, generate a **new Ed25519 key** and store it securely (file mode `0600`).
- Invoke the system `ssh` command with `-i ~/.local/share/treadmill-tb/ssh-key <USER@IP>`.
This ensures a consistent, Treadmill-managed SSH key without interfering with your other SSH configurations.
## Examples
1. **Login**:
```
./tml login
```
CLI will prompt you for your username and password if they are not provided by any other means.
2. **Enqueue a job**:
```
./tml job enqueue 46ebc6946f7c4a10922bf1f539cd7351ce8670781e081d18babf1affdef6f577 \
--ssh-keys "ssh-rsa AAAAB3NzaC1yc2E...,ssh-ed25519 AAAAC3NzaC1lZDI1NTE5..." \
--restart-count 3 \
--parameters '{"key1":{"value":"value1","secret":false},"key2":{"value":"value2","secret":true}}' \
--tag-config 'test_tag_config' \
--timeout 3600
```
3. **List all jobs**:
```
./tml job list
```
4. **Check job status**:
```
./tml job status <JOB_ID>
```
5. **Cancel a job**:
```
./tml job cancel <JOB_ID>
```
6. **SSH into a running job**:
```
# Example: connect to user root at IP 10.42.0.123
./tml job ssh root@10.42.0.123
```
- The CLI will generate or reuse an Ed25519 key at `~/.local/share/treadmill-tb/ssh-key` and then run:
```
ssh -i ~/.local/share/treadmill-tb/ssh-key root@10.42.0.123
```
## Verbose Logging
To enable verbose logging, add the `-v` or `--verbose` flag to your command:
```
./tml -v job enqueue <IMAGE_ID>
```
This will output debug-level logs, which can be helpful for troubleshooting.
## Notes
- The image ID should be a 64-character hexadecimal string.
- Job IDs are UUIDs.
- The `--parameters` option requires a JSON string in the following format:
```json
{
"key1": { "value": "value1", "secret": false },
"key2": { "value": "value2", "secret": true }
}
```
Each parameter must have a "value" (as a string) and a "secret" (as a boolean) field.
For more detailed information about each command and its options, use the `--help` flag with any command or subcommand.