Update entrypoint.sh
Browse files- entrypoint.sh +69 -161
entrypoint.sh
CHANGED
|
@@ -1,161 +1,69 @@
|
|
| 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 |
-
var config = {
|
| 71 |
-
gateway: {
|
| 72 |
-
auth: gatewayToken
|
| 73 |
-
? { mode: "token", token: gatewayToken }
|
| 74 |
-
: { mode: "password", password: gatewayPassword },
|
| 75 |
-
controlUi: {
|
| 76 |
-
allowInsecureAuth: true,
|
| 77 |
-
dangerouslyAllowHostHeaderOriginFallback: true
|
| 78 |
-
},
|
| 79 |
-
trustedProxies: trustedProxies
|
| 80 |
-
},
|
| 81 |
-
agents: {
|
| 82 |
-
defaults: {
|
| 83 |
-
model: defaultModel
|
| 84 |
-
}
|
| 85 |
-
},
|
| 86 |
-
// Write detected keys into env.vars so OpenClaw injects them into its runtime.
|
| 87 |
-
// This is the official OpenClaw mechanism for env-based provider auth.
|
| 88 |
-
env: { vars: {} }
|
| 89 |
-
};
|
| 90 |
-
|
| 91 |
-
detectedKeys.forEach(function(k) {
|
| 92 |
-
config.env.vars[k] = (process.env[k] || "").trim();
|
| 93 |
-
});
|
| 94 |
-
|
| 95 |
-
// ---- Telegram - auto detect best reachable node ----
|
| 96 |
-
async function detectTelegramNode(nodes, token) {
|
| 97 |
-
for (var i = 0; i < nodes.length; i++) {
|
| 98 |
-
var node = nodes[i];
|
| 99 |
-
try {
|
| 100 |
-
await new Promise(function(resolve, reject) {
|
| 101 |
-
var req = https.get(node + "/bot" + token + "/getMe", function(res) {
|
| 102 |
-
if (res.statusCode === 200) resolve(true);
|
| 103 |
-
else reject(new Error("HTTP " + res.statusCode));
|
| 104 |
-
});
|
| 105 |
-
req.on("error", reject);
|
| 106 |
-
req.setTimeout(4000, function() { req.destroy(); reject(new Error("Timeout")); });
|
| 107 |
-
});
|
| 108 |
-
console.log("[setup] Telegram node reachable: " + node);
|
| 109 |
-
// Strip trailing slash
|
| 110 |
-
return node.replace(/\/$/, "");
|
| 111 |
-
} catch (e) {
|
| 112 |
-
console.log("[setup] Telegram node unreachable: " + node + " (" + e.message + ")");
|
| 113 |
-
}
|
| 114 |
-
}
|
| 115 |
-
return null;
|
| 116 |
-
}
|
| 117 |
-
|
| 118 |
-
var TELEGRAM_NODES = [
|
| 119 |
-
"https://api.telegram.org",
|
| 120 |
-
"https://tg-api.vercel.app",
|
| 121 |
-
"https://telegram-bot-api.vercel.app"
|
| 122 |
-
];
|
| 123 |
-
|
| 124 |
-
async function setupTelegram() {
|
| 125 |
-
var token = (process.env.TELEGRAM_BOT_TOKEN || "").trim();
|
| 126 |
-
if (!token) { console.log("[setup] Telegram: disabled"); return; }
|
| 127 |
-
var apiRoot = await detectTelegramNode(TELEGRAM_NODES, token);
|
| 128 |
-
var finalRoot = apiRoot || TELEGRAM_NODES[0];
|
| 129 |
-
config.channels = {
|
| 130 |
-
telegram: {
|
| 131 |
-
enabled: true,
|
| 132 |
-
accounts: { main: { botToken: token, apiRoot: finalRoot } }
|
| 133 |
-
}
|
| 134 |
-
};
|
| 135 |
-
console.log("[setup] Telegram: enabled, apiRoot=" + finalRoot);
|
| 136 |
-
}
|
| 137 |
-
|
| 138 |
-
// ---- main ----
|
| 139 |
-
async function main() {
|
| 140 |
-
await setupTelegram();
|
| 141 |
-
|
| 142 |
-
try {
|
| 143 |
-
fs.mkdirSync(STATE_DIR, { recursive: true });
|
| 144 |
-
if (fs.existsSync(CONFIG_PATH)) {
|
| 145 |
-
fs.copyFileSync(CONFIG_PATH, CONFIG_PATH + ".bak");
|
| 146 |
-
}
|
| 147 |
-
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), "utf-8");
|
| 148 |
-
} catch (e) {
|
| 149 |
-
console.error("[setup] Write failed: " + e.message);
|
| 150 |
-
process.exit(1);
|
| 151 |
-
}
|
| 152 |
-
|
| 153 |
-
console.log("[setup] Done. auth=" + (gatewayToken ? "token" : "password") +
|
| 154 |
-
" model=" + defaultModel + " proxies=" + trustedProxies.length +
|
| 155 |
-
" env.vars=" + detectedKeys.length);
|
| 156 |
-
}
|
| 157 |
-
|
| 158 |
-
main().then(() => process.exit(0)).catch(function(e) {
|
| 159 |
-
console.error("[setup] Fatal: " + e.message);
|
| 160 |
-
process.exit(1);
|
| 161 |
-
});
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
|
| 3 |
+
# resolve OPENCLAW_HOME
|
| 4 |
+
|
| 5 |
+
if mkdir -p /data/.openclaw 2>/dev/null; then
|
| 6 |
+
export OPENCLAW_HOME=/data
|
| 7 |
+
else
|
| 8 |
+
export OPENCLAW_HOME=/home/user
|
| 9 |
+
mkdir -p /home/user/.openclaw
|
| 10 |
+
fi
|
| 11 |
+
|
| 12 |
+
echo “[entrypoint] OPENCLAW_HOME=$OPENCLAW_HOME”
|
| 13 |
+
|
| 14 |
+
# dynamically export all provider keys so openclaw gateway can read them
|
| 15 |
+
|
| 16 |
+
# OpenClaw’s official mechanism: reads provider keys directly from process env vars
|
| 17 |
+
|
| 18 |
+
# matches: *_API_KEY *_SECRET_KEY *_ACCESS_TOKEN *_BOT_TOKEN *_AUTH_TOKEN *_APP_KEY
|
| 19 |
+
|
| 20 |
+
# excludes: OPENCLAW_ SPACE_ SYSTEM_ HF_SPACE NODE_ prefixes
|
| 21 |
+
|
| 22 |
+
for VAR in $(env | cut -d= -f1); do
|
| 23 |
+
case “$VAR” in
|
| 24 |
+
OPENCLAW_*|SPACE_*|SYSTEM_*|HF_SPACE*|NODE_*) continue ;;
|
| 25 |
+
esac
|
| 26 |
+
case “$VAR” in
|
| 27 |
+
*_API_KEY|*_SECRET_KEY|*_ACCESS_TOKEN|*_BOT_TOKEN|*_AUTH_TOKEN|*_APP_KEY)
|
| 28 |
+
eval VAL=$$VAR
|
| 29 |
+
if [ -n “$VAL” ]; then
|
| 30 |
+
export “$VAR”
|
| 31 |
+
echo “[entrypoint] exported: $VAR”
|
| 32 |
+
fi
|
| 33 |
+
;;
|
| 34 |
+
esac
|
| 35 |
+
done
|
| 36 |
+
|
| 37 |
+
# always export HF_TOKEN for dataset sync
|
| 38 |
+
|
| 39 |
+
export HF_TOKEN=”${HF_TOKEN:-}”
|
| 40 |
+
|
| 41 |
+
# restore from HF Dataset (30s timeout, non-fatal)
|
| 42 |
+
|
| 43 |
+
if [ -n “$HF_TOKEN” ] && [ -n “$HF_DATASET_ID” ]; then
|
| 44 |
+
echo “[entrypoint] Restoring from dataset ${HF_DATASET_ID}…”
|
| 45 |
+
timeout 30 sh /app/hf-sync.sh restore || echo “[entrypoint] Restore skipped (non-fatal)”
|
| 46 |
+
fi
|
| 47 |
+
|
| 48 |
+
# write openclaw config
|
| 49 |
+
|
| 50 |
+
node /app/spaces/huggingface/setup-hf-config.mjs || true
|
| 51 |
+
|
| 52 |
+
# run security check (non-fatal)
|
| 53 |
+
|
| 54 |
+
if [ -f /app/security-check.sh ]; then
|
| 55 |
+
sh /app/security-check.sh || true
|
| 56 |
+
fi
|
| 57 |
+
|
| 58 |
+
echo “[entrypoint] starting gateway…”
|
| 59 |
+
|
| 60 |
+
# start background sync loop
|
| 61 |
+
|
| 62 |
+
if [ -n “$HF_TOKEN” ] && [ -n “$HF_DATASET_ID” ]; then
|
| 63 |
+
sh /app/hf-sync.sh loop &
|
| 64 |
+
echo “[entrypoint] sync loop started (interval=${HF_SYNC_INTERVAL:-3600}s)”
|
| 65 |
+
fi
|
| 66 |
+
|
| 67 |
+
# FIX: must use ASCII hyphens – not en-dashes
|
| 68 |
+
|
| 69 |
+
exec node /app/openclaw.mjs gateway –allow-unconfigured –bind lan –port 7860
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|