# Using the Protect CLI

## What you’ll learn

This guide teaches you how to effectively use the Edera Protect CLI (`protect`), understand its output formats, and troubleshoot common issues. By the end, you’ll be comfortable managing zones, workloads, and interpreting CLI responses.

**Target audience**: Developers and platform engineers new to Edera

**Time to complete**: 15 minutes

## Prerequisites

Before starting this guide, ensure you have:

- [ ]  Edera Protect installed and running on your system
- [ ]  Basic familiarity with Linux command-line tools
- [ ]  The `protect` CLI available in your PATH

ℹ️

**Check installation status**: Run `protect --version` to verify installation. If the command is not found, see the [installation guides](https://docs.edera.dev/guides/install/).

**For detailed command syntax**: This guide focuses on practical usage. For complete command reference with all options and flags, see the [CLI Reference Documentation](https://docs.edera.dev/reference/cli/).

## Overview of steps

1. **CLI Fundamentals** - Basic command structure and help system
2. **Managing Zones** - Creating, listing, and monitoring zones
3. **Working with Workloads** - Launching and managing containerized applications
4. **Managing Images** - Pulling, caching, and removing container images
5. **Understanding Output Formats** - Interpreting different output types
6. **Debugging and Troubleshooting** - Common issues and solutions

## Step 1: CLI fundamentals

The `protect` CLI follows a hierarchical command structure. Understanding this structure is key to using it effectively.

### Basic command structure

```bash
protect [global-options] <command> [subcommand] [options] [arguments]
```

### Getting help

The CLI includes comprehensive help at every level:

```bash
# Get general help
protect --help

# Get help for a specific command
protect zone --help

# Get help for a subcommand
protect zone launch --help
```

### Connection options

You can specify a custom connection to the Edera daemon:

```bash
# Use default connection
protect zone list

# Connect to a remote daemon
protect --connection tcp://192.168.1.100:8080 zone list

# Use a different local socket
protect --connection unix:///tmp/custom-daemon.socket zone list
```

Most users use the default connection. Options vary by command. Use `--help` with any command to see available options.

**Expected Result**: You should see detailed help output explaining available commands and options.

## Step 2: Managing zones

Zones are isolated virtual environments where your workloads run. Let’s explore basic zone operations.

### Launching your first zone

```bash
# Launch a basic zone
protect zone launch --name my-test-zone --wait
```

**Important**: The `--wait` flag makes the command wait for the zone to be ready before returning.

### Listing zones

```bash
# List all zones in table format
protect zone list

# List zones in JSON format for automation
protect zone list --output json
```

### Monitoring zone status

```bash
# Watch zone changes in real-time
protect zone watch

# Get detailed info about a specific zone
protect zone list my-test-zone --output json-pretty
```

## Step 3: Working with workloads

Workloads are containerized applications running inside zones. Here’s how to manage them effectively.

### Launching a workload

```bash
# Launch a simple workload in an existing zone
protect workload launch --zone my-test-zone --name web-server nginx:latest

# Launch with custom command and wait for it to start
protect workload launch --zone my-test-zone --name debug-shell --wait ubuntu:latest /bin/bash
```

### Executing commands in workloads

```bash
# Run a basic command in a workload (works with minimal containers)
protect workload exec web-server /bin/sh -c "ls /"

# Run system commands in full containers
protect workload exec debug-shell ps aux

# Get an interactive shell
protect workload exec --tty debug-shell /bin/bash
```

### Managing workload lifecycle

```bash
# List all workloads
protect workload list

# Stop a workload
protect workload stop web-server

# Start a stopped workload
protect workload start web-server

# Destroy a workload permanently
protect workload destroy web-server --wait
```

## Step 4: Managing images

Edera caches container images locally for faster workload launches. Here’s how to manage the image cache:

### Listing cached images

```bash
# View all cached images
protect image list

# Get detailed JSON output
protect image list --output json-pretty
```

### Listing kernel variants

Kernel variants are alternate zone kernel images with different features or extra capabilities or drivers.
The daemon resolves from its `[zone.kernel-variants]` configuration.

To list the usable kernel variants currently recognized by the daemon:

```bash
# Variants accepted by `zone launch --kernel-variant` and the
# `dev.edera/kernel-variant` pod annotation
protect image list-kernel-variants
```

See [Selecting a zone kernel variant](https://docs.edera.dev/guides/kernel/kernel-variants/) for more details.

### Pulling images

```bash
# Pull an image into the cache
protect image pull nginx:latest

# Force overwrite existing cached image
protect image pull --overwrite-cache redis:alpine
```

### Removing images

Images are identified by digest when removing:

```bash
# First, list images to get the digest
protect image list --output table

# Remove by digest
protect image remove sha256:abc123...def456
```

### Image formats

Edera supports multiple image formats:

- **squashfs** (default) - Compressed, read-only filesystem
- **tar** - Standard tar archive
- **directory** - Uncompressed directory

Use `squashfs` for production environments and `directory` for development and debugging.

## Step 5: Understanding output formats

The `protect` CLI supports multiple output formats to suit different use cases. Understanding these formats helps with both human readability and automation.

### Available output formats

Most `list` commands support these formats:

- `table` (default) - Human-readable tabular output
- `json` - Machine-readable JSON, one object
- `json-pretty` - Formatted JSON for human viewing
- `jsonl` - JSON Lines, one object per line
- `yaml` - YAML format
- `key-value` - Simple key=value pairs
- `simple` - Minimal text output

### Examples of different outputs

```bash
# Human-friendly table (default)
protect zone list
```

**Expected Output (Table)**:

```text
NAME          ID       STATE   CPUS   MEMORY
my-test-zone  abc123   ready   1      1024MB
```

```bash
# Machine-readable JSON
protect zone list --output json-pretty
```

**Expected Output (JSON)**:

```json
{
  "zones": [{
    "name": "my-test-zone",
    "id": "abc123",
    "state": "ready",
    "resources": {
      "cpus": 1,
      "memory": "1024MB"
    }
  }]
}
```

### Interpreting zone states

Zones progress through these states:

- **creating** - Zone is being initialized
- **created** - Zone exists but isn’t ready yet
- **ready** - Zone is running and available for workloads
- **exited** - Zone has stopped
- **destroying** - Zone is being torn down
- **destroyed** - Zone has been removed
- **failed** - Zone encountered an error

### Interpreting workload states

Workloads have these states:

- **creating** - Workload is being set up
- **created** - Workload exists but isn’t running
- **running** - Workload is actively executing
- **completed** - Workload finished successfully
- **destroying** - Workload is being removed
- **destroyed** - Workload has been removed
- **failed** - Workload encountered an error

## Step 6: Debugging and troubleshooting

When things don’t work as expected, the CLI provides several tools to help diagnose issues.

### Checking system status

```bash
# Check if the Edera daemon is running
protect host status

# View system topology
protect host cpu-topology
```

### Viewing logs

```bash
# Follow zone logs in real-time
protect zone logs my-test-zone --follow

# View hypervisor debug information
protect host hv-debug-info
```

### Using selectors for filtering

Selectors help you filter resources by state:

```bash
# List only failed zones
protect zone list --selector status.state=failed

# List only running workloads
protect workload list --selector status.state=running
```

## Troubleshooting common issues

### Zone won’t start

**Problem**: Zone gets stuck in “creating” state
**Solution**:

1. Check daemon status: `protect host status`
2. Look for resource constraints in the logs
3. Verify sufficient CPU/memory resources are available

### Workload shows “completed” instead of “running”

**Problem**: Service workloads transition to `completed` state immediately

```bash
protect workload launch --zone my-zone --name web nginx:latest
protect workload list
# Shows: web | completed (expected: running)
```

**The `completed` state indicates**: The container process exited. This does not indicate success.

**Common causes**:

- **Port conflicts**: Service cannot bind to required port (most common)
- **Configuration errors**: Service fails to start
- **Permission or resource issues**

**How to debug**:

1. **Launch with shell for investigation:**

```bash
protect workload launch --zone my-zone --name debug nginx:latest /bin/bash
```

2. **Manually start service to see the actual error:**

```bash
protect workload exec debug nginx -g "daemon off;"
# Example output: "bind() to 0.0.0.0:80 failed (98: Address already in use)"
```

3. **Fix the issue and verify:**

```bash
# Example: Fix port conflict
protect workload exec debug /bin/sh -c "sed 's/listen.*80/listen 8080/' /etc/nginx/conf.d/default.conf > /tmp/new.conf && cp /tmp/new.conf /etc/nginx/conf.d/default.conf"

# Test the fix
protect workload exec debug nginx -g "daemon off;"
# Service should now remain running
```

### Connection refused

**Problem**: CLI returns “connection refused” error

```text
Error connecting to protect daemon, is the service running?

Raw error:
Error: transport error
Caused by:
    0: tcp connect error
    1: tcp connect error
    2: Connection refused (os error 111)
```

**Solution**:

1. For local connections: Check if daemon is running: `systemctl status protect-daemon`
2. Check socket permissions: `ls -la /var/lib/edera/protect/daemon.socket`
3. For TCP connections: Verify the daemon is configured to listen on TCP (see “Enabling TCP Access” below)

### Enabling TCP access

By default, the daemon only listens on a Unix socket. To enable TCP access:

1. **Create systemd override:**

```bash
sudo systemctl edit protect-daemon
```

2. **Add TCP configuration:**

```ini
[Service]
ExecStart=
ExecStart=/usr/sbin/protect-daemon -l tcp://0.0.0.0:8080
```

3. **Apply changes:**

```bash
sudo systemctl daemon-reload
sudo systemctl restart protect-daemon
```

4. **Test the connection:**

```bash
protect --connection tcp://localhost:8080 zone list
```

Secure TCP access in production environments with appropriate firewall rules and authentication.

### Workload image pull fails

**Problem**: Cannot pull container image
**Solution**:

1. Test image pull manually: `protect image pull <image-name>`
2. Check network connectivity from the zone
3. Verify image name and tag are correct
4. For private registries, ensure authentication is configured

### Workload exec failures

**Problem**: `protect workload exec` fails with “execvpe failed”

```bash
# This might fail in minimal containers
protect workload exec web-server ps aux
# Error: execvpe failed
```

**Solution**: The command may not exist in the container image

1. **Try basic commands first:**

```bash
protect workload exec web-server /bin/sh -c "ls /"
```

2. **Use containers with more tools** for debugging:

```bash
protect workload exec debug-shell ps aux
```

3. **Check what’s available:**

```bash
protect workload exec web-server /bin/sh -c "which ps || echo 'ps not found'"
```

Minimal containers such as NGINX may lack debugging tools. Use full OS images such as Ubuntu or Alpine when you need comprehensive tooling.

### Permission denied in workload

**Problem**: Commands in workload fail with permission errors
**Solution**:

1. Check if workload needs elevated privileges: `--privileged`
2. Verify user/group settings: `--user <user>``--group <group>`
3. Review capability requirements: `--cap-add <capability>`

## Next steps

- **CLI reference**: For complete command syntax and all available options, see the [CLI Reference Documentation](https://docs.edera.dev/reference/cli/)
- **Deep dive into zones**: Learn about [advanced zone configuration](https://docs.edera.dev/guides/advanced)
- **GPU workloads**: See how to [use GPUs with Edera](https://docs.edera.dev/guides/gpu)
- **Monitoring**: Set up [observability and monitoring](https://docs.edera.dev/guides/observability)

## Summary

**Key Points**:

- The `protect` CLI uses a hierarchical command structure with comprehensive help
- Zones provide isolated environments; workloads run containerized apps within zones
- Multiple output formats support both human use and automation
- State information helps you understand the lifecycle of resources
- Built-in debugging tools help diagnose and resolve common issues

**You can now**: Use the Edera Protect CLI confidently, interpret command outputs, and troubleshoot basic issues.

Last updated on 2026-07-20
