diff --git a/tasks/enduro-trails/prototype/check-health.js b/tasks/enduro-trails/prototype/check-health.js new file mode 100644 index 0000000..e9612b7 --- /dev/null +++ b/tasks/enduro-trails/prototype/check-health.js @@ -0,0 +1,37 @@ +const { Client } = require('ssh2'); + +const conn = new Client(); + +function exec(conn, cmd, timeout) { + return new Promise((resolve) => { + const t = setTimeout(() => resolve({ out: 'TIMEOUT', err: '' }), timeout || 20000); + conn.exec(cmd, (err, stream) => { + if (err) { clearTimeout(t); return resolve({ out: '', err: err.message }); } + let out = '', e = ''; + stream.on('data', d => out += d); + stream.stderr.on('data', d => e += d); + stream.on('close', () => { clearTimeout(t); resolve({ out: out.trim(), err: e.trim() }); }); + }); + }); +} + +conn.on('ready', async () => { + let r; + + r = await exec(conn, 'docker ps | grep 5558'); + console.log('container:', r.out || r.err); + + r = await exec(conn, 'curl -s http://localhost:5558/api/health'); + console.log('health:', r.out || r.err); + + r = await exec(conn, 'curl -s http://localhost:5558/ | head -5'); + console.log('root:', r.out || r.err); + + r = await exec(conn, 'docker logs enduro-trails-app-1 2>&1 | tail -20'); + console.log('logs:', r.out || r.err); + + conn.end(); +}); + +conn.on('error', (err) => { console.error('SSH error:', err.message); process.exit(1); }); +conn.connect({ host: '82.22.50.71', username: 'slin', password: 'motoZ@yaz2010', readyTimeout: 15000 }); diff --git a/tasks/enduro-trails/prototype/deploy-prod.js b/tasks/enduro-trails/prototype/deploy-prod.js new file mode 100644 index 0000000..e249236 --- /dev/null +++ b/tasks/enduro-trails/prototype/deploy-prod.js @@ -0,0 +1,113 @@ +const { Client } = require('ssh2'); + +const conn = new Client(); + +function exec(conn, cmd, timeout) { + return new Promise((resolve) => { + const t = setTimeout(() => resolve({ out: 'TIMEOUT', err: '' }), timeout || 20000); + conn.exec(cmd, (err, stream) => { + if (err) { clearTimeout(t); return resolve({ out: '', err: err.message }); } + let out = '', e = ''; + stream.on('data', d => out += d); + stream.stderr.on('data', d => e += d); + stream.on('close', () => { clearTimeout(t); resolve({ out: out.trim(), err: e.trim() }); }); + }); + }); +} + +conn.on('ready', async () => { + console.log('=== SSH Connected ===\n'); + + // Step 1: Check data in new repo + console.log('--- Step 1: Check data ---'); + let r = await exec(conn, 'ls /home/slin/repos/enduro-trails/data/', 10000); + console.log('data/:', r.out || r.err); + + r = await exec(conn, 'ls /home/slin/repos/enduro-trails/data/terrain/ 2>/dev/null | head -5'); + console.log('terrain/:', r.out || '(empty or missing)'); + + r = await exec(conn, 'ls -lh /home/slin/repos/enduro-trails/data/centralfederal.sqlite 2>/dev/null || echo "MISSING"'); + console.log('sqlite:', r.out); + + // Step 2: Stop old container + console.log('\n--- Step 2: Stop old container ---'); + r = await exec(conn, 'cd /home/slin/enduro-trails/prototype && docker compose down 2>&1', 30000); + console.log('compose down:', r.out || r.err); + + if (r.out.includes('TIMEOUT') || r.err.includes('not found')) { + console.log('Trying docker stop/rm fallback...'); + r = await exec(conn, 'docker stop prototype-enduro-trails-1 2>&1 && docker rm prototype-enduro-trails-1 2>&1', 20000); + console.log('fallback:', r.out || r.err); + } + + // Step 3: Write new docker-compose.yml + console.log('\n--- Step 3: Write docker-compose.yml ---'); + const composeContent = `version: "3.8" +services: + app: + build: . + ports: + - "5558:5558" + volumes: + - ./data:/app/data + - ./src/web:/app/src/web + environment: + - DATABASE_URL=sqlite:///./data/enduro.db + - DATA_PATH=/app/data/centralfederal.sqlite + - TILES_DIR=/app/data/terrain + - TERRAIN_DIR=/app/data/terrain + - STATIC_DIR=/app/src/web + - OSRM_URL=http://172.22.0.1:5559 + - PORT=5558 + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:5558/api/health"] + interval: 30s + timeout: 5s + retries: 3 + restart: unless-stopped +`; + + // Write via heredoc + const writeCmd = `cat > /home/slin/repos/enduro-trails/docker-compose.yml << 'ENDOFFILE'\n${composeContent}ENDOFFILE`; + r = await exec(conn, writeCmd, 10000); + console.log('write compose:', r.err || 'ok'); + + // Verify + r = await exec(conn, 'cat /home/slin/repos/enduro-trails/docker-compose.yml'); + console.log('compose content:\n', r.out); + + // Step 4: Build and start new container + console.log('\n--- Step 4: docker compose up --build ---'); + console.log('(this may take 3-5 minutes, timeout set to 8 min)'); + r = await exec(conn, 'cd /home/slin/repos/enduro-trails && docker compose up -d --build 2>&1', 480000); + console.log('compose up:', r.out || r.err); + + // Step 5: Health check + console.log('\n--- Step 5: Health check ---'); + // Wait a moment for container to start + await new Promise(res => setTimeout(res, 5000)); + + r = await exec(conn, 'curl -s http://localhost:5558/api/health', 15000); + console.log('health:', r.out || r.err); + + r = await exec(conn, 'curl -s http://localhost:5558/ 2>&1 | head -3', 15000); + console.log('root:', r.out || r.err); + + r = await exec(conn, 'docker ps | grep 5558', 10000); + console.log('container status:', r.out || '(not found)'); + + console.log('\n=== DONE ==='); + conn.end(); +}); + +conn.on('error', (err) => { + console.error('SSH error:', err.message); + process.exit(1); +}); + +conn.connect({ + host: '82.22.50.71', + username: 'slin', + password: 'motoZ@yaz2010', + readyTimeout: 15000 +}); diff --git a/tasks/enduro-trails/prototype/fix-port-rebuild.js b/tasks/enduro-trails/prototype/fix-port-rebuild.js new file mode 100644 index 0000000..0296f0e --- /dev/null +++ b/tasks/enduro-trails/prototype/fix-port-rebuild.js @@ -0,0 +1,55 @@ +const { Client } = require('ssh2'); + +const conn = new Client(); + +function exec(conn, cmd, timeout) { + return new Promise((resolve) => { + const t = setTimeout(() => resolve({ out: 'TIMEOUT', err: '' }), timeout || 20000); + conn.exec(cmd, (err, stream) => { + if (err) { clearTimeout(t); return resolve({ out: '', err: err.message }); } + let out = '', e = ''; + stream.on('data', d => out += d); + stream.stderr.on('data', d => e += d); + stream.on('close', () => { clearTimeout(t); resolve({ out: out.trim(), err: e.trim() }); }); + }); + }); +} + +conn.on('ready', async () => { + let r; + + // Fix Dockerfile: replace hardcoded 5556 with 5558 + console.log('--- Patching Dockerfile ---'); + r = await exec(conn, `sed -i 's/ENV PORT=5556/ENV PORT=5558/; s/EXPOSE 5556/EXPOSE 5558/; s/--port", "5556"/--port", "5558"/' /home/slin/repos/enduro-trails/Dockerfile`); + console.log('sed:', r.err || 'ok'); + + r = await exec(conn, 'cat /home/slin/repos/enduro-trails/Dockerfile'); + console.log('Dockerfile after patch:\n', r.out); + + // Rebuild and restart + console.log('\n--- Rebuild and restart ---'); + r = await exec(conn, 'cd /home/slin/repos/enduro-trails && docker compose down 2>&1', 30000); + console.log('down:', r.out || r.err); + + r = await exec(conn, 'cd /home/slin/repos/enduro-trails && docker compose up -d --build 2>&1', 480000); + console.log('up:', r.out || r.err); + + // Wait for startup + await new Promise(res => setTimeout(res, 8000)); + + // Health check + console.log('\n--- Health check ---'); + r = await exec(conn, 'curl -s http://localhost:5558/api/health', 15000); + console.log('health:', r.out || r.err); + + r = await exec(conn, 'docker ps | grep 5558'); + console.log('container:', r.out || r.err); + + r = await exec(conn, 'docker logs enduro-trails-app-1 2>&1 | tail -10'); + console.log('logs:', r.out || r.err); + + conn.end(); +}); + +conn.on('error', (err) => { console.error('SSH error:', err.message); process.exit(1); }); +conn.connect({ host: '82.22.50.71', username: 'slin', password: 'motoZ@yaz2010', readyTimeout: 15000 }); diff --git a/tasks/enduro-trails/prototype/inspect-dockerfile.js b/tasks/enduro-trails/prototype/inspect-dockerfile.js new file mode 100644 index 0000000..22da643 --- /dev/null +++ b/tasks/enduro-trails/prototype/inspect-dockerfile.js @@ -0,0 +1,31 @@ +const { Client } = require('ssh2'); + +const conn = new Client(); + +function exec(conn, cmd, timeout) { + return new Promise((resolve) => { + const t = setTimeout(() => resolve({ out: 'TIMEOUT', err: '' }), timeout || 20000); + conn.exec(cmd, (err, stream) => { + if (err) { clearTimeout(t); return resolve({ out: '', err: err.message }); } + let out = '', e = ''; + stream.on('data', d => out += d); + stream.stderr.on('data', d => e += d); + stream.on('close', () => { clearTimeout(t); resolve({ out: out.trim(), err: e.trim() }); }); + }); + }); +} + +conn.on('ready', async () => { + let r; + + r = await exec(conn, 'cat /home/slin/repos/enduro-trails/Dockerfile'); + console.log('Dockerfile:\n', r.out || r.err); + + r = await exec(conn, 'cat /home/slin/repos/enduro-trails/src/api/main.py | head -50'); + console.log('main.py head:\n', r.out || r.err); + + conn.end(); +}); + +conn.on('error', (err) => { console.error('SSH error:', err.message); process.exit(1); }); +conn.connect({ host: '82.22.50.71', username: 'slin', password: 'motoZ@yaz2010', readyTimeout: 15000 });