| Concern | Assessment |
|---|---|
| Browser automation fragility | Temporary bridge only — swap to API when ready. Portal ordering UI rarely changes. |
| Leaseweb provisioning time | Absorbed by pre-warming. User never sees it. |
| Pool cost (idle servers) | 3 warm VPS1 = $10.50/mo idle. Covered by the first sale. |
| 20–30s delivery claim | SSH in + inject config only. No package installs. Already proven in xCloud pipeline. |
| Pool depletion on demand spike | Low-watermark alerts + configurable min. Vultr handles overflow transparently. |
| Reseller account limits | Confirm max concurrent orders with Aziz before go-live. |
leaseweb_server_poolid
region -- 'us-east-1', 'sin-01', etc.
size -- 'VPS02_1' (4vCPU/6GB), 'VPS02_2', etc.
status -- ordering | provisioning | warming | warm | assigned | failed
leaseweb_id -- VPS ID from Leaseweb (once delivered)
ip_address
root_password -- encrypted
ssh_key_id
ordered_at
warmed_at
assigned_at
assigned_to -- xCloud server_id
notes
PoolManager::getWarm(region, size) // atomic find + lock warm server
PoolManager::assign(poolServer, xServer) // mark assigned, link to xCloud server
PoolManager::getInventory() // counts per region/size/status
PoolManager::needsReplenishment() // compare against thresholds
Runs every 5 minutes OR triggered on each assignment:
OrderLeasewebServer jobWarmServer job// scripts/leaseweb/order-vps.js
const { chromium } = require('playwright');
async function orderVPS({ region, size, credentials }) {
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://my.leaseweb.com/login');
await page.fill('#username', credentials.email);
await page.fill('#password', credentials.password);
await page.click('[type=submit]');
// Handle 2FA via stored TOTP secret...
await page.goto('https://my.leaseweb.com/order/vps');
await page.selectOption('[name=location]', region);
await page.click(`[data-plan="${size}"]`);
await page.selectOption('[name=os]', 'Ubuntu 22.04');
await page.click('[data-term="1_MONTH"]');
await page.click('[data-action=confirm-order]');
const vpsId = await page.textContent('[data-vps-id]');
await browser.close();
return { vpsId, orderedAt: new Date().toISOString() };
}
orderVPS() with a single API call. Zero other changes.# Base system
apt-get update && apt-get upgrade -y
apt-get install -y curl wget git unzip nginx
# Node.js 22 LTS
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs
# OpenClaw CLI
npm install -g openclaw@latest
# Directory structure
mkdir -p /root/.openclaw/workspace /root/.openclaw/credentials /var/log/openclaw
chmod 700 /root/.openclaw
# Mark warm
touch /root/.openclaw/.warm_ready
echo "WARM_TIMESTAMP=$(date -u +%s)" >> /root/.openclaw/.env
Estimated: 5–8 minutes after Leaseweb delivers the VPS. Runs in background, user never sees it.
PoolManager::getWarm(region, size) → reserve server atomically (<1ms)openclaw gateway install --port 18789 --token $TOKEN --force// config/leaseweb_pool.php
return [
'pools' => [
['region' => 'us-east-1', 'size' => 'VPS02_1', 'min' => 3, 'max' => 6], // highest demand
['region' => 'us-west-1', 'size' => 'VPS02_1', 'min' => 2, 'max' => 4],
['region' => 'eu-west-3', 'size' => 'VPS02_1', 'min' => 2, 'max' => 4], // Amsterdam
['region' => 'eu-central-1', 'size' => 'VPS02_1', 'min' => 1, 'max' => 3], // Frankfurt
['region' => 'sin-01', 'size' => 'VPS02_1', 'min' => 1, 'max' => 3], // Singapore
['region' => 'au-1', 'size' => 'VPS02_1', 'min' => 1, 'max' => 2],
// Larger sizes — lower demand, 1 warm per key region
['region' => 'us-east-1', 'size' => 'VPS02_2', 'min' => 1, 'max' => 2],
['region' => 'eu-west-3', 'size' => 'VPS02_2', 'min' => 1, 'max' => 2],
],
];
Initial idle cost: ~12 warm servers × $3.50/mo avg = ~$42/mo. Single sale covers it.
| Vultr (current) | Leaseweb (proposed) | |
|---|---|---|
| VPS1 cost (4vCPU/6GB) | ~$24/mo | $3.50/mo |
| xCloud sell price | ~$30/mo | ~$30/mo |
| Gross margin | $6/mo (~20%) | $26.50/mo (~88%) |
| At 10 sales/day × 30 days | $1,800/mo | $7,950/mo |
Phase 1→3 target: 2 weeks.
leaseweb_server_pool migration + modelApp\Services\Leaseweb\PoolManager serviceApp\Jobs\Leaseweb\PoolReplenisherJob (every 5 min via scheduler)App\Jobs\Leaseweb\OrderVPSJob (triggers browser script, polls delivery)App\Jobs\Leaseweb\WarmServerJob (SSH + provision base stack)App\Jobs\Leaseweb\DeliverFromPoolJob (inject config, start gateway)config/leaseweb_pool.php)scripts/leaseweb/order-vps.js (Playwright)OrderVPSJobresources/views/scripts/leaseweb/warm-server.blade.php (base install)resources/views/scripts/leaseweb/inject-config.blade.php (fast path)install-gateway-service, onboard-coreDeliverFromPoolJob when pool available| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Portal UI change breaks automation | Medium | Medium | Fall back to Vultr; fix within hours |
| Leaseweb delivery >2h | Low | Low | Pool absorbs it; user never sees it |
| 2FA blocks automation | Low | High | TOTP stored secret; or request portal API key auth |
| Reseller limits block bulk ordering | Low | Medium | Pre-clear with Aziz |
| Pool over-allocated | Low | Low | Set max thresholds; auto-expire after 30 days |