File size: 5,688 Bytes
3b47d98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#!/usr/bin/env bash
set -uo pipefail

ENV_FILE="/etc/profile.d/openclaw-env.sh"
LOG_FILE="/var/log/openclaw/env-update.log"
CACHE_FILE="/tmp/hf-env-cache.json"
EXPORT_FILE="/tmp/env-from-api.sh"

DRY_RUN=false

usage() {
    cat <<EOF
Usage: $0 [OPTIONS]

从 Hugging Face API 获取最新的环境变量并更新到本地文件。

必需的环境变量:
  HF_TOKEN 或 HF_API_TOKEN    HuggingFace API Token
  OPENCLAW_HF_SPACE_ID              HuggingFace Space ID

选项:
  --dry-run    预览将从 API 获取的环境变量,不写入任何文件
  -h, --help   显示本帮助信息

使用示例:
  # 预览模式(不写入文件)
  HF_TOKEN=hf_xxxxx OPENCLAW_HF_SPACE_ID=username/space-name $0 --dry-run

  # 正常执行
  HF_TOKEN=hf_xxxxx OPENCLAW_HF_SPACE_ID=username/space-name $0

  # 使用 HF_API_TOKEN
  HF_API_TOKEN=hf_xxxxx OPENCLAW_HF_SPACE_ID=username/space-name $0

EOF
}

while [[ $# -gt 0 ]]; do
    case "$1" in
        --dry-run)
            DRY_RUN=true
            shift
            ;;
        -h|--help)
            usage
            exit 0
            ;;
        *)
            echo "Unknown option: $1"
            usage
            exit 1
            ;;
    esac
done

mkdir -p /var/log/openclaw

log() {
    echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $1" | tee -a "$LOG_FILE"
}

log_dry() {
    echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] [DRY-RUN] $1"
}

fetch_and_show_env() {
    local OPENCLAW_HF_SPACE_ID="$1"
    local api_token="$2"

    if [[ -z "$OPENCLAW_HF_SPACE_ID" ]] || [[ -z "$api_token" ]]; then
        log "Error: OPENCLAW_HF_SPACE_ID or API_TOKEN is empty"
        return 1
    fi

    log "Fetching environment variables from HF API for space: $OPENCLAW_HF_SPACE_ID"

    local response
    response=$(curl -s -w "\n%{http_code}" \
        -H "Authorization: Bearer $api_token" \
        "https://huggingface.co/api/spaces/$OPENCLAW_HF_SPACE_ID/runtime" 2>/dev/null)

    local http_code=$(echo "$response" | tail -n1)
    local body=$(echo "$response" | sed '$d')

    if [[ "$http_code" != "200" ]]; then
        log "Error: API request failed with HTTP $http_code"
        log "Response: $body"
        return 1
    fi

    echo "$body" > "$CACHE_FILE"

    if ! command -v jq >/dev/null 2>&1; then
        log "Error: jq not available, cannot parse API response"
        return 1
    fi

    local env_count
    env_count=$(echo "$body" | jq '.env // {} | length')
    if [[ "$env_count" -eq 0 ]]; then
        log "Warning: API response contains no environment variables"
        return 1
    fi

    log "Found $env_count environment variables from API"
    echo ""

    if [[ "$DRY_RUN" == "true" ]]; then
        log_dry "========== DRY-RUN: Environment Variables to be fetched =========="
    else
        : > "$EXPORT_FILE"
    fi

    local sensitive_pattern="(TOKEN|KEY|SECRET|PASSWORD|ENCRYPTION_PASSWORD)"
    while IFS='=' read -r key value; do
        if [[ -n "$key" && "$key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then
            if [[ "$DRY_RUN" == "true" ]]; then
                if [[ "$key" =~ $sensitive_pattern ]]; then
                    log_dry "  $key=<sensitive>"
                else
                    log_dry "  $key=$value"
                fi
            else
                printf 'export %s=%q\n' "$key" "$value" >> "$EXPORT_FILE"
                if [[ "$key" =~ $sensitive_pattern ]]; then
                    log "Exported: $key=<sensitive>"
                else
                    log "Exported: $key=$value"
                fi
            fi
        fi
    done < <(echo "$body" | jq -r '.env // {} | to_entries[] | "\(.key)=\(.value)"')

    if [[ "$DRY_RUN" == "true" ]]; then
        log_dry "========== DRY-RUN: Would write to files =========="
        log_dry "  ENV_FILE=$ENV_FILE (skipped in dry-run)"
        log_dry "  EXPORT_FILE=$EXPORT_FILE (skipped in dry-run)"
        log_dry "========================================================"
        rm -f "$CACHE_FILE"
    fi

    return 0
}

main() {
    log "Starting environment update from HF API..."
    if [[ "$DRY_RUN" == "true" ]]; then
        log "*** DRY-RUN MODE: No files will be written ***"
    fi

    local OPENCLAW_HF_SPACE_ID="${OPENCLAW_HF_SPACE_ID:-}"
    if [[ -z "$OPENCLAW_HF_SPACE_ID" ]]; then
        log "Error: OPENCLAW_HF_SPACE_ID is required but not set"
        log "Please set OPENCLAW_HF_SPACE_ID environment variable"
        exit 1
    fi

    local hf_token="${HF_TOKEN:-${HF_API_TOKEN:-}}"
    if [[ -z "$hf_token" ]]; then
        log "Error: HF_TOKEN is required but not set"
        log "Please set HF_TOKEN or HF_API_TOKEN environment variable"
        exit 1
    fi

    if ! fetch_and_show_env "$OPENCLAW_HF_SPACE_ID" "$hf_token"; then
        log "Warning: Failed to fetch env from API"
        exit 1
    fi

    if [[ "$DRY_RUN" == "true" ]]; then
        log "Dry-run completed. No files were modified."
        exit 0
    fi

    if [[ -x /usr/local/bin/save-env.sh ]]; then
        if [[ -f "$EXPORT_FILE" && -s "$EXPORT_FILE" ]]; then
            log "Sourcing API exports before calling save-env.sh"
            source "$EXPORT_FILE"
        fi
        /usr/local/bin/save-env.sh
        log "Environment file updated successfully"
    else
        log "Error: save-env.sh not found or not executable"
        exit 1
    fi

    rm -f "$EXPORT_FILE"

    log "Current non-sensitive variables:"
    log "  OPENCLAW_BACKUP_DATASET_REPO: ${OPENCLAW_BACKUP_DATASET_REPO:-<not set>}"
    log "  OPENCLAW_BACKUP_CRON: ${OPENCLAW_BACKUP_CRON:-*/12 * * * *}"
    log "  OPENCLAW_BACKUP_ENCRYPTION_ENABLED: ${OPENCLAW_BACKUP_ENCRYPTION_ENABLED:-<not set>}"
}

main "$@" 2>&1 | tee -a "$LOG_FILE"