# CLI 自动化

{% hint style="success" %}
**先决条件：** 安装 SDK（`pip install clore-ai`）并配置您的 API 密钥。请参阅 [Python 快速入门](https://docs.clore.ai/guides/guides_v2-zh/ru-men/python-quickstart) 如果您还没有。
{% endhint %}

## 基本工作流

核心循环： **搜索 → 部署 → 连接 → 取消**.

```bash
# 1. 寻找 GPU
clore search --gpu "RTX 4090" --max-price 2.0 --sort price --limit 5

# 2. 部署（使用第 1 步中的服务器 ID）
clore deploy 142 \
  --image cloreai/ubuntu22.04-cuda12 \
  --type on-demand \
  --currency bitcoin \
  --ssh-password MySecurePass \
  --port 22:tcp \
  --port 8888:http

# 3. 检查您的订单
clore orders

# 4. SSH 登录到服务器
clore ssh 38

# 5. 完成后取消
clore cancel 38

# 6. 检查钱包余额
clore wallets
```

***

## CLI 命令参考

| 命令                                    | 说明             |
| ------------------------------------- | -------------- |
| `clore search`                        | 搜索 GPU 市场      |
| `clore deploy <server_id>`            | 创建新订单          |
| `clore orders`                        | 列出活动订单         |
| `clore orders --completed`            | 列出包括已完成在内的所有订单 |
| `clore ssh <order_id>`                | SSH 登录到活动订单    |
| `clore cancel <order_id>`             | 取消订单           |
| `clore wallets`                       | 显示钱包余额         |
| `clore servers`                       | 列出您托管的服务器      |
| `clore server-config <name>`          | 显示服务器配置        |
| `clore spot <server_id>`              | 查看服务器的现货市场     |
| `clore spot-price <order_id> <price>` | 为订单设置现货价格      |
| `clore config set <key> <value>`      | 设置配置值          |
| `clore config get <key>`              | 获取配置值          |
| `clore config show`                   | 显示所有配置         |

***

## 使用 CLI 脚本

### 部署并等待 SSH

```bash
#!/bin/bash
# deploy-and-connect.sh — 部署服务器并在准备好时 SSH 登录

set -euo pipefail

SERVER_ID=${1:?Usage: $0 <server_id>}
IMAGE=${2:-cloreai/ubuntu22.04-cuda12}
PASSWORD="AutoDeploy$(date +%s)"

echo "🚀 正在部署服务器 $SERVER_ID..."
clore deploy "$SERVER_ID" \
  --image "$IMAGE" \
  --type on-demand \
  --currency bitcoin \
  --ssh-password "$PASSWORD" \
  --port 22:tcp

echo "⏳ 等待订单就绪..."
sleep 15

echo "📦 活动订单："
clore orders

echo ""
echo "🔑 SSH 密码： $PASSWORD"
echo "💡 连接方式： clore ssh <order_id>"
```

### 查找最便宜的 GPU 并部署

```bash
#!/bin/bash
# cheapest-gpu.sh — 查找并部署匹配条件的最便宜 GPU

GPU_MODEL=${1:-"RTX 4090"}
MAX_PRICE=${2:-5.0}

echo "🔍 正在搜索每小时低于 \$$MAX_PRICE 的最便宜 $GPU_MODEL..."
clore search --gpu "$GPU_MODEL" --max-price "$MAX_PRICE" --sort price --limit 5

echo ""
read -p "输入要部署的服务器 ID（或输入 'q' 退出）： " SERVER_ID

if [ "$SERVER_ID" = "q" ]; then
    echo "已取消。"
    exit 0
fi

read -sp "SSH 密码： " SSH_PASS
echo ""

clore deploy "$SERVER_ID" \
  --image cloreai/ubuntu22.04-cuda12 \
  --type on-demand \
  --currency bitcoin \
  --ssh-password "$SSH_PASS" \
  --port 22:tcp \
  --port 8888:http

echo "✅ 已部署！查看 'clore orders' 以获取状态。"
```

### 取消所有订单

```bash
#!/bin/bash
# cancel-all.sh — 取消所有活动订单

echo "📦 当前订单："
clore orders

echo ""
read -p "取消所有活动订单？（yes/no）： " CONFIRM

if [ "$CONFIRM" = "yes" ]; then
    # 使用 Python 单行脚本因为 CLI 每次只能取消一个
    python3 -c "
from clore_ai import CloreAI
client = CloreAI()
orders = client.my_orders()
for o in orders:
    client.cancel_order(o.id, issue='Batch cleanup')
    print(f'Cancelled order {o.id}')
print(f'Done. Cancelled {len(orders)} orders.')
"
else
    echo "已取消。"
fi
```

***

## CI/CD 集成

### GitHub Actions：为训练部署 GPU

```yaml
# .github/workflows/train.yml
名称：GPU Training

触发：
  workflow_dispatch：
    输入：
      gpu_model：
        说明：'GPU 型号'
        默认：'RTX 4090'
      max_price：
        说明：'最高每小时价格（美元）'
        默认：'2.0'

环境变量：
  CLORE_API_KEY: ${{ secrets.CLORE_API_KEY }}

作业：
  train：
    运行于：ubuntu-latest
    步骤：
      - uses: actions/checkout@v4

      - 名称：安装 clore-ai
        运行：pip install clore-ai

      - 名称：查找并部署 GPU
        运行： |
          python3 << 'EOF'
          import time, os
          from clore_ai import CloreAI

          client = CloreAI()

          # 查找最便宜的匹配 GPU
          servers = client.marketplace(
              gpu="${{ github.event.inputs.gpu_model }}",
              max_price_usd=float("${{ github.event.inputs.max_price }}")
          )
          servers.sort(key=lambda s: s.price_usd or float("inf"))

          if not servers:
              print("没有可用的服务器！")
              exit(1)

          best = servers[0]
          print(f"正在在服务器 {best.id} 上部署：{best.gpu_model} @ ${best.price_usd:.4f}/h")

          order = client.create_order(
              server_id=best.id,
              image="cloreai/ubuntu22.04-cuda12",
              type="on-demand",
              currency="bitcoin",
              ssh_password=os.environ.get("SSH_PASSWORD", "CITraining123"),
              ports={"22": "tcp"},
              command="bash /workspace/train.sh"
          )

          print(f"订单 {order.id} 已创建")

          # 等待就绪
          for _ in range(30):
              orders = client.my_orders()
              o = next((x for x in orders if x.id == order.id), None)
              if o and o.pub_cluster:
                  print(f"已就绪： {o.pub_cluster}")
                  break
              time.sleep(10)

          # 保存订单 ID 以便清理
          with open(os.environ["GITHUB_ENV"], "a") as f:
              f.write(f"ORDER_ID={order.id}\n")
          EOF

      - 名称：等待训练完成
        运行： |
          echo "训练进行中..."
          # 在此添加您的监控逻辑
          sleep 60

      - 名称：清理 GPU
        if: always()
        运行： |
          python3 -c "
          from clore_ai import CloreAI
          import os
          client = CloreAI()
          order_id = int(os.environ.get('ORDER_ID', 0))
          if order_id:
              client.cancel_order(order_id, issue='CI job complete')
              print(f'Cancelled order {order_id}')
          "
```

### GitLab CI：批处理

```yaml
# .gitlab-ci.yml
gpu-batch-job：
  阶段：process
  镜像：python:3.11
  变量：
    CLORE_API_KEY: $CLORE_API_KEY
  before_script：
    - pip install clore-ai
  脚本：
    - |
      python3 << 'EOF'
      from clore_ai import CloreAI
      import time

      client = CloreAI()

      servers = client.marketplace(gpu="RTX 4090", max_price_usd=3.0)
      if not servers:
          print("没有可用的 GPU")
          exit(1)

      servers.sort(key=lambda s: s.price_usd or float("inf"))
      order = client.create_order(
          server_id=servers[0].id,
          image="cloreai/ubuntu22.04-cuda12",
          type="spot",
          currency="bitcoin",
          spot_price=0.00005,
          ports={"22": "tcp"}
      )
      print(f"已部署：订单 {order.id}")

      # ... 执行工作 ...

      client.cancel_order(order.id)
      print("完成并已清理")
      EOF
  after_script：
    - |
      python3 -c "
      from clore_ai import CloreAI
      client = CloreAI()
      for o in client.my_orders():
          client.cancel_order(o.id, issue='CI cleanup')
      "
```

***

## 监控

### 定期检查订单

```bash
#!/bin/bash
# monitor.sh — 每 60 秒检查一次订单

while true; do
    echo "=== $(date) ==="
    clore orders
    clore wallets
    echo ""
    sleep 60
done
```

### Python 监控脚本

```python
#!/usr/bin/env python3
"""monitor-orders.py — 监控活动订单并在出现问题时发出警报。"""

import time
from clore_ai import CloreAI

POLL_INTERVAL = 60  # 秒
LOW_BALANCE_THRESHOLD = 0.001  # BTC

def monitor():
    client = CloreAI()

    while True:
        try:
            # 检查订单
            orders = client.my_orders()
            print(f"[{time.strftime('%H:%M:%S')}] 活动订单： {len(orders)}")
            for o in orders:
                print(f"  订单 {o.id}：类型={o.type}, IP={o.pub_cluster or 'pending'}")

            # 检查余额
            wallets = client.wallets()
            for w in wallets:
                if w.name.lower() == "bitcoin" and w.balance < LOW_BALANCE_THRESHOLD:
                    print(f"  ⚠️  BTC 余额低： {w.balance:.8f}")

        except Exception as e:
            print(f"  ❌ 错误： {e}")

        time.sleep(POLL_INTERVAL)

if __name__ == "__main__":
    monitor()
```

***

## 批量操作

### 在多台服务器上部署

```bash
#!/bin/bash
# batch-deploy.sh — 在多台服务器上部署

SERVER_IDS=(142 305 891 450)
IMAGE="cloreai/ubuntu22.04-cuda12"
PASSWORD="BatchRun$(date +%s)"

for SID in "${SERVER_IDS[@]}"; do
    echo "🚀 正在在服务器 $SID 上部署..."
    clore deploy "$SID" \
      --image "$IMAGE" \
      --type on-demand \
      --currency bitcoin \
      --ssh-password "$PASSWORD" \
      --port 22:tcp \
      || echo "⚠️  部署 $SID 失败"
    sleep 6  # 遵守速率限制
done

echo ""
echo "📦 所有订单："
clore orders
echo "🔑 密码： $PASSWORD"
```

### 使用 Python（异步）批量部署

```python
#!/usr/bin/env python3
"""batch-deploy.py — 在多台服务器上并发部署。"""

import asyncio
from clore_ai import AsyncCloreAI
from clore_ai.exceptions import CloreAPIError

async def batch_deploy(server_ids, image="cloreai/ubuntu22.04-cuda12"):
    async with AsyncCloreAI() as client:
        tasks = [
            client.create_order(
                server_id=sid,
                image=image,
                type="on-demand",
                currency="bitcoin",
                ssh_password="BatchPass123",
                ports={"22": "tcp"}
            )
            for sid in server_ids
        ]

        results = await asyncio.gather(*tasks, return_exceptions=True)

        for sid, result in zip(server_ids, results):
            if isinstance(result, CloreAPIError):
                print(f"❌ 服务器 {sid}：{result}")
            elif isinstance(result, Exception):
                print(f"❌ 服务器 {sid}：{result}")
            else:
                print(f"✅ 服务器 {sid}：订单 {result.id}")

if __name__ == "__main__":
    import sys
    server_ids = [int(x) for x in sys.argv[1:]]
    if not server_ids:
        print("用法：python batch-deploy.py 142 305 891")
        exit(1)
    asyncio.run(batch_deploy(server_ids))
```

用法：

```bash
python batch-deploy.py 142 305 891
```

### 现货市场扫描器

```bash
#!/bin/bash
# spot-scanner.sh — 为一列服务器扫描现货价格

SERVERS=(6 12 42 100)

echo "📊 现货市场扫描 — $(date)"
echo "---"

for SID in "${SERVERS[@]}"; do
    echo "服务器 $SID："
    clore spot "$SID"
    echo ""
done
```

***

## 定时任务

### 每日 GPU 价格检查

```bash
# 添加到 crontab： crontab -e
# 每天上午 9 点运行
0 9 * * * CLORE_API_KEY=your_key /usr/local/bin/clore search --gpu "RTX 4090" --sort price --limit 5 >> /var/log/clore-prices.log 2>&1
```

### 每小时余额检查

```bash
# 每小时检查余额
0 * * * * CLORE_API_KEY=your_key /usr/local/bin/clore wallets >> /var/log/clore-balance.log 2>&1
```

***

## 提示

1. **始终设置 `CLORE_API_KEY`** 作为脚本和 CI 中的环境变量
2. **添加 `sleep 6`** 在 bash 循环中的部署命令之间以遵守速率限制
3. **使用 `--type spot`** 用于批处理/CI 作业 — 更便宜且可中断
4. **在 `after_script`** / `if: always()` 中取消订单以避免遗忘计费
5. **将 SSH 密码存储在密钥中** （GitHub Secrets、GitLab CI 变量等）
6. **使用 `clore orders --completed`** 以审计过去的使用情况

***

## 下一步

* [Python SDK 指南](https://docs.clore.ai/guides/guides_v2-zh/gao-ji/python-sdk) — 带有异步模式的完整 SDK 参考
* [批处理处理](https://docs.clore.ai/guides/guides_v2-zh/gao-ji/batch-processing) — 处理大型 AI 工作负载
* [API 集成](https://docs.clore.ai/guides/guides_v2-zh/gao-ji/api-integration) — 将 AI 服务连接到您的应用


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-zh/gao-ji/cli-automation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
