]> ##Vast.ai Monitor ###2026.09.17.0040 - The plugin now has an icon everywhere Unraid shows one. The Plugins page entry, the Settings and Utilities nav entry and the dashboard tile all use the Vast.ai mark instead of a generic glyph or a missing image. - Icons are now transparent PNGs rather than opaque dark squares, so they sit correctly on the light Unraid themes as well as the dark ones. - The Plugins page now shows a description instead of just the plugin name. ###2026.09.16.2315 - Fix: plugin updates now actually install. Previously the plugin manager skipped every file that already existed, so an update reported success but kept running the old code until the next reboot. - Fix: the plugin icon is now installed. The manifest used a BASE64 element that the plugin manager does not implement, so no image was ever written. - Fix: listed machines showed a per-GPU rate in the same column that shows a per-machine rate once rented. An 8-GPU host under-reported its asking price by 8x. - Fix: multi-GPU hosts were misclassified. gpu_occupancy is a per-GPU string, so comparing it to a single character never matched, and treating any non-empty value as rented could show an idle host as rented at 0.00/hr. - Fix: theme support. 19 of 26 CSS variable references named variables Unraid does not define, so every theme fell back to dark colours. - Fix: the tile can be collapsed again, using the native dashboard control. - Fix: stale data is now labelled STALE instead of ONLINE, and a warning is shown. - Fix: an upstream outage no longer increases outbound API traffic. - Fix: Test Connection no longer overwrites the shared dashboard cache. - Security: test_key is accepted on POST only. The GET path bypassed CSRF validation. - Security: the API key is scrubbed from the config on uninstall. - Removed three settings that had no effect: SHOW_TEMP, SHOW_SPECS, SHOW_OFFLINE. rm -rf &emhttp; mkdir -p &plugin; mkdir -p &emhttp;/include mkdir -p &emhttp;/javascript mkdir -p &emhttp;/styles mkdir -p &emhttp;/images mkdir -p &emhttp;/icons if [ ! -f &plugin;/&name;.cfg ]; then cp &emhttp;/default.cfg &plugin;/&name;.cfg fi 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 =')" Menu="Dashboard:0" --- ]]>
Vast.ai

_(Vast.ai Dashboard Widget Configuration)_

_(Monitor your listed Vast.ai machines, active rentals, real-time hourly income, and hardware telemetry right on the Unraid Dashboard.)_

_(Vast.ai API Key)_: :
_(Obtain or generate your API key from the)_ _(Vast.ai Key Management Console)_. _(Default Refresh Interval)_: : _(Interval for automatic background status polling on the dashboard.)_ _(Local Cache Expiration)_: : _(Protects against API rate limits across multiple open dashboard tabs.)_ _(Dashboard Placement)_: : _(Show Account Balance)_: :   :
]]>
false, 'not_configured' => true, 'error' => 'Vast.ai API Key is not configured. Please open Settings → Utilities → Vast.ai Monitor to enter your API key.', 'timestamp' => time(), ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); exit; } // Check cache if not forcing refresh and not testing an ad-hoc key if (!$force_reload && !$is_test_key && file_exists($cache_file)) { $mtime = filemtime($cache_file); $age = time() - $mtime; if ($age < $cache_ttl) { $cached_data = @file_get_contents($cache_file); if ($cached_data) { $json = json_decode($cached_data, true); if (is_array($json) && !empty($json['success'])) { $json['cached'] = true; $json['cache_age'] = $age; echo json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); exit; } } } } // Negative caching. After an upstream failure, do not retry on every poll. // Without this an outage makes outbound traffic go UP, because the stale path // serves the cache without refreshing its mtime, so every later request retries. $backoff_file = $cache_file . '.backoff'; $backoff_ttl = 30; if (!$force_reload && !$is_test_key && file_exists($backoff_file) && (time() - filemtime($backoff_file)) < $backoff_ttl && file_exists($cache_file)) { $stale_data = @file_get_contents($cache_file); $json = $stale_data ? json_decode($stale_data, true) : null; if (is_array($json)) { $json['stale'] = true; $json['warning'] = 'Vast.ai API unreachable. Showing cached data.'; echo json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); exit; } } /** * Helper to execute HTTP GET via cURL */ function vast_api_get(string $url, int $timeout = 9): array { $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 5, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => $timeout, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_USERAGENT => 'VastAI-Unraid-Widget/1.0', CURLOPT_HTTPHEADER => [ 'Accept: application/json', ], ]); $response = curl_exec($ch); $errno = curl_errno($ch); $error = curl_error($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return [ 'code' => $httpCode, 'errno' => $errno, 'error' => $error, 'response' => $response, ]; } $api_key_enc = urlencode($api_key); $machines_url = "https://console.vast.ai/api/v0/machines/?owner=me&api_key={$api_key_enc}"; $user_url = "https://console.vast.ai/api/v0/users/current/?api_key={$api_key_enc}"; // 1. Fetch hosted machines $mach_res = vast_api_get($machines_url); if ($mach_res['errno'] !== 0 || $mach_res['code'] !== 200) { // Record the failure so the negative-cache backoff above engages and we do // not hammer a down upstream once per poll per open dashboard tab. if (!$is_test_key) { @touch($backoff_file); } // If request failed, check for stale cache fallback (unless testing a custom key) if (!$is_test_key && file_exists($cache_file)) { $stale_data = @file_get_contents($cache_file); if ($stale_data) { $json = json_decode($stale_data, true); if (is_array($json)) { $json['stale'] = true; $json['warning'] = 'Vast.ai API connection error (' . ($mach_res['error'] ?: "HTTP {$mach_res['code']}") . '). Showing cached data.'; echo json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); exit; } } } $errMsg = $mach_res['error'] ?: "HTTP {$mach_res['code']}"; if ($mach_res['code'] === 401 || $mach_res['code'] === 403) { $resp_json = @json_decode($mach_res['response'] ?? '', true); if (is_array($resp_json) && !empty($resp_json['msg'])) { $errMsg = $resp_json['msg'] . " (HTTP {$mach_res['code']})"; } else { $errMsg = "Invalid API Key or unauthorized (HTTP {$mach_res['code']}). Please verify your key from console.vast.ai/manage-keys."; } } echo json_encode([ 'success' => false, 'error' => $errMsg, 'http_code' => $mach_res['code'], 'timestamp' => time(), ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); exit; } $raw_machines_data = json_decode($mach_res['response'], true); if (is_array($raw_machines_data) && isset($raw_machines_data['success']) && $raw_machines_data['success'] === false) { $errMsg = $raw_machines_data['msg'] ?? $raw_machines_data['error'] ?? 'API error'; echo json_encode([ 'success' => false, 'error' => $errMsg, 'http_code' => $mach_res['code'], 'timestamp' => time(), ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); exit; } $raw_machines = $raw_machines_data['machines'] ?? []; // 2. Fetch User Account Balance (optional) $account_info = [ 'balance' => 0.0, 'credit' => 0.0, 'email' => '', ]; if ($show_balance) { $user_res = vast_api_get($user_url, 5); if ($user_res['code'] === 200 && !empty($user_res['response'])) { $u = json_decode($user_res['response'], true); if (is_array($u)) { $account_info['balance'] = (float) ($u['balance'] ?? 0.0); $account_info['credit'] = (float) ($u['credit'] ?? 0.0); $account_info['email'] = (string) ($u['email'] ?? ''); } } } // 3. Process each machine $processed_machines = []; $total_earn_hour = 0.0; $total_earn_day = 0.0; $rented_count = 0; $total_gpus = 0; $rented_gpus = 0; foreach ($raw_machines as $m) { $mach_id = (int) ($m['id'] ?? $m['machine_id'] ?? 0); $hostname = (string) ($m['hostname'] ?? "Machine #{$mach_id}"); $num_gpus = max(1, (int) ($m['num_gpus'] ?? 1)); $total_gpus += $num_gpus; // Clean GPU Name (remove NVIDIA prefix if repetitive) $gpu_name = (string) ($m['gpu_name'] ?? 'GPU'); $gpu_name = preg_replace('/^NVIDIA\s+/i', '', $gpu_name); $gpu_ram_mb = (int) ($m['gpu_ram'] ?? 0); $gpu_ram_gb = $gpu_ram_mb > 0 ? round($gpu_ram_mb / 1024, 1) : 0; $listed = !empty($m['listed']); $timeout = (float) ($m['timeout'] ?? 0); $is_online = ($timeout <= 0.0); // Rentals detection $running_rentals = (int) ($m['current_rentals_running'] ?? 0); $resident_rentals = (int) ($m['current_rentals_resident'] ?? 0); $on_demand_rentals = (int) ($m['current_rentals_running_on_demand'] ?? 0); $reserved_rentals = (int) ($m['current_rentals_running_reserved'] ?? 0); $occupancy_raw = (string) ($m['gpu_occupancy'] ?? ''); $occupancy_code = strtoupper(trim($occupancy_raw)); // gpu_occupancy is a PER-GPU string, one character per GPU, so an 8-GPU host // returns something like "DDxxxxxx". Two consequences: // 1. Never compare it for equality against a single character. That can // never match a multi-GPU host. // 2. Never treat "non-empty" as rented. An idle host still returns a // full-length string of placeholder characters. // Testing for the known occupancy letters avoids depending on whatever the // idle placeholder character happens to be. $occ_on_demand = (strpos($occupancy_code, 'D') !== false); $occ_reserved = (strpos($occupancy_code, 'R') !== false); $occ_interruptible = (strpos($occupancy_code, 'I') !== false); $occ_any = $occ_on_demand || $occ_reserved || $occ_interruptible; $is_rented = ($running_rentals > 0) || $occ_any; // Rental status classification if (!$is_online) { $status_key = 'offline'; $status_label = 'Offline'; $status_color = 'red'; } elseif ($is_rented) { $rented_count++; $rented_gpus += $num_gpus; if ($on_demand_rentals > 0 || $occ_on_demand) { $status_key = 'rented_on_demand'; $status_label = 'Rented (On-Demand)'; $status_color = 'green'; } elseif ($reserved_rentals > 0 || $occ_reserved) { $status_key = 'rented_reserved'; $status_label = 'Rented (Reserved)'; $status_color = 'purple'; } elseif ($occ_interruptible || $running_rentals > 0) { $status_key = 'rented_interruptible'; $status_label = 'Rented (Interruptible)'; $status_color = 'yellow'; } else { $status_key = 'rented'; $status_label = 'Rented'; $status_color = 'green'; } } elseif ($listed) { $status_key = 'listed'; $status_label = 'Listed & Available'; $status_color = 'blue'; } else { $status_key = 'unlisted'; $status_label = 'Unlisted'; $status_color = 'gray'; } // Pricing & Earnings $earn_hour = (float) ($m['earn_hour'] ?? 0.0); $earn_day = (float) ($m['earn_day'] ?? 0.0); $listed_gpu_cost = (float) ($m['listed_gpu_cost'] ?? 0.0); $min_bid_price = (float) ($m['min_bid_price'] ?? 0.0); $total_earn_hour += $earn_hour; $total_earn_day += $earn_day; // GPU Temp & Reliability $gpu_temp = isset($m['gpu_max_cur_temp']) && $m['gpu_max_cur_temp'] !== null ? round((float) $m['gpu_max_cur_temp'], 1) : null; $reliability = isset($m['reliability2']) && $m['reliability2'] !== null ? round(((float) $m['reliability2']) * 100, 1) : null; $verification = (string) ($m['verification'] ?? 'unverified'); // Host Hardware Specs $cpu_name = (string) ($m['cpu_name'] ?? ''); // Clean up CPU branding $cpu_name = preg_replace('/(Processor|12-Cores|16-Cores|8-Cores|6-Cores|24-Cores|32-Cores|64-Cores)/i', '', $cpu_name); $cpu_name = trim(preg_replace('/\s+/', ' ', $cpu_name)); $cpu_cores = (int) ($m['cpu_cores'] ?? 0); $cpu_ram_mb = (int) ($m['cpu_ram'] ?? 0); $cpu_ram_gb = $cpu_ram_mb > 0 ? round($cpu_ram_mb / 1024, 1) : 0; $disk_space_gb = (float) ($m['disk_space'] ?? 0); $avail_disk_gb = (float) ($m['avail_disk_space'] ?? 0); $inet_down_mbps = round((float) ($m['inet_down'] ?? 0), 1); $inet_up_mbps = round((float) ($m['inet_up'] ?? 0), 1); $processed_machines[] = [ 'id' => $mach_id, 'hostname' => $hostname, 'num_gpus' => $num_gpus, 'gpu_name' => $gpu_name, 'gpu_ram_gb' => $gpu_ram_gb, 'gpu_temp' => $gpu_temp, 'reliability' => $reliability, 'verification' => $verification, 'is_online' => $is_online, 'listed' => $listed, 'is_rented' => $is_rented, 'status_key' => $status_key, 'status_label' => $status_label, 'status_color' => $status_color, 'occupancy_code' => $occupancy_code, 'running_rentals' => $running_rentals, 'resident_rentals' => $resident_rentals, 'earn_hour' => $earn_hour, 'earn_day' => $earn_day, 'listed_gpu_cost' => $listed_gpu_cost, 'min_bid_price' => $min_bid_price, 'cpu_name' => $cpu_name, 'cpu_cores' => $cpu_cores, 'cpu_ram_gb' => $cpu_ram_gb, 'disk_space_gb' => $disk_space_gb, 'avail_disk_gb' => $avail_disk_gb, 'inet_down_mbps' => $inet_down_mbps, 'inet_up_mbps' => $inet_up_mbps, ]; } $payload = [ 'success' => true, 'timestamp' => time(), 'summary' => [ 'total_machines' => count($processed_machines), 'rented_machines' => $rented_count, 'total_gpus' => $total_gpus, 'rented_gpus' => $rented_gpus, 'total_earn_hour' => round($total_earn_hour, 4), 'total_earn_day' => round($total_earn_day, 4), 'account_balance' => round($account_info['balance'], 2), 'account_credit' => round($account_info['credit'], 2), ], 'machines' => $processed_machines, ]; // Write to cache file atomically. Never on a test-key request, or clicking // Test Connection would publish that account's fleet to every dashboard tab. if (!$is_test_key) { @unlink($backoff_file); $tmp_cache = $cache_file . '.' . uniqid('tmp', true); if (@file_put_contents($tmp_cache, json_encode($payload, JSON_UNESCAPED_SLASHES)) !== false) { if (!@rename($tmp_cache, $cache_file)) { @unlink($tmp_cache); } } else { @unlink($tmp_cache); } } echo json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); ]]> '10 s', '30' => '30 s', '60' => '60 s', '120' => '2 m', '0' => 'off'] as $v => $lab) { $sel = ($interval === (int) $v) ? ' selected' : ''; $intOpts .= ""; } $mytiles['vastai'][$column] = << $t_title Connecting…
$t_load
EOT; ]]>
/g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } function formatMoney(amount, decimals = 2) { const num = parseFloat(amount) || 0; return '$' + num.toFixed(decimals); } function formatRate(amount) { const num = parseFloat(amount) || 0; if (num === 0) return '$0.00/hr'; if (num < 0.01) return '$' + num.toFixed(4) + '/hr'; return '$' + num.toFixed(3) + '/hr'; } /** * Render table row for a single machine */ function renderMachineRow(m, index) { const isRented = !!m.is_rented; const isOnline = !!m.is_online; const isListed = !!m.listed; // Status Column let statusHtml = ''; if (!isOnline) { statusHtml = ` offline
Unreachable
`; } else if (isRented) { // occupancy_code is a per-GPU string (one char per GPU), so test for the // letter rather than comparing the whole string to a single character. const occ = m.occupancy_code || ''; let occDesc = 'Active'; if (occ.includes('D')) occDesc = 'On-Demand'; else if (occ.includes('R')) occDesc = 'Reserved'; else if (occ.includes('I')) occDesc = 'Interruptible'; const runningCount = m.running_rentals || 1; statusHtml = ` active
${occDesc} • ${runningCount} ${runningCount === 1 ? 'job' : 'jobs'}
`; } else if (isListed) { statusHtml = ` listed
Ready for rent
`; } else { statusHtml = ` unlisted
Not listed
`; } // Rate Column let rateHtml = ''; if (isRented) { rateHtml = ` +${formatRate(m.earn_hour)}
Est. ${formatMoney(m.earn_day)}/day
`; } else if (isListed && isOnline) { // listed_gpu_cost and min_bid_price are PER GPU, while earn_hour in the // branch above is per machine. Scale to machine level so the same column // always means the same thing, and show the per-GPU ask alongside it. const gpus = m.num_gpus || 1; const askMachine = (parseFloat(m.listed_gpu_cost) || 0) * gpus; const minMachine = (parseFloat(m.min_bid_price) || 0) * gpus; rateHtml = ` ${formatRate(askMachine)}
Min: ${formatRate(minMachine)}${gpus > 1 ? ` · ${formatRate(m.listed_gpu_cost)}/GPU` : ''}
`; } else { rateHtml = ` $0.00/hr
-
`; } // Temperature Column let tempHtml = '-'; if (m.gpu_temp !== null && m.gpu_temp !== undefined) { let tempClass = 'vast-temp-cool'; if (m.gpu_temp >= 80) tempClass = 'vast-temp-hot'; else if (m.gpu_temp >= 65) tempClass = 'vast-temp-warm'; tempHtml = `${m.gpu_temp} °C`; } // Reliability Column (SMART healthy style) let reliabHtml = '-'; if (m.reliability !== null && m.reliability !== undefined) { if (m.reliability >= 95) { reliabHtml = ` ${m.reliability}%`; } else { reliabHtml = ` ${m.reliability}%`; } } // Utilization Bar Column let utilPercent = 0; let fillClass = 'fill-gray'; if (isRented) { utilPercent = 100; fillClass = (m.occupancy_code || '').includes('I') ? 'fill-amber' : 'fill-green'; } else if (isListed) { utilPercent = 0; fillClass = 'fill-blue'; } const utilHtml = ` ${utilPercent}%
`; // Main row let html = `
${escapeHtml(m.hostname)}
#${escapeHtml(m.id)} • ${m.num_gpus}x ${escapeHtml(m.gpu_name)} ${m.gpu_ram_gb ? `(${m.gpu_ram_gb} GB)` : ''}
${statusHtml} ${rateHtml} ${tempHtml} ${reliabHtml} ${utilHtml} `; // Expandable hardware details row if (showHardwareDetails) { const details = []; if (m.cpu_name) { details.push(`
CPU: ${escapeHtml(m.cpu_name)}${m.cpu_cores ? ` (${m.cpu_cores}C)` : ''}
`); } if (m.cpu_ram_gb) { details.push(`
RAM: ${m.cpu_ram_gb} GB
`); } if (m.disk_space_gb) { details.push(`
Disk: ${m.disk_space_gb} GB (${m.avail_disk_gb} GB Free)
`); } if (m.inet_down_mbps && m.inet_up_mbps) { details.push(`
Net: ${m.inet_down_mbps} ↓ / ${m.inet_up_mbps} ↑ Mbps
`); } if (m.verification) { details.push(`
Host Status: ${escapeHtml(m.verification)}
`); } html += `
${details.join('')}
`; } return html; } function renderTile(data) { const $container = $('#vast_widget_container'); const $subtitle = $('#vast_subtitle'); const sum = data.summary || {}; const totalEarn = sum.total_earn_hour || 0; const totalEarnDay = sum.total_earn_day || 0; const balance = sum.account_balance || 0; const rentedCount = sum.rented_machines || 0; const totalCount = sum.total_machines || 0; const machines = data.machines || []; // Subtitle. The backend emits stale/cached/cache_age on its degradation // paths, so surface them instead of always claiming ONLINE. const rented = `${rentedCount} of ${totalCount} Rented`; if (data.stale) { $subtitle.html(`Status: STALE • ${rented}`); } else if (data.cached && data.cache_age > 0) { $subtitle.html(`Status: ONLINE • ${rented} • cached ${data.cache_age}s ago`); } else { $subtitle.html(`Status: ONLINE • ${rented}`); } // Summary Line (matching PROCESSOR "Total Power 103.74 W | Temperature: 78 °C" / ARRAY "3.98 TB used...") let earnSummary = ''; if (totalEarn > 0) { earnSummary = `Total Earnings: +${formatRate(totalEarn)} (Est. ${formatMoney(totalEarnDay, 2)}/day)`; } else { earnSummary = `Total Earnings: $0.00/hr (Idle)`; } const balanceText = balance > 0 ? ` | Balance: ${formatMoney(balance, 2)}` : ''; const detailsToggleLabel = showHardwareDetails ? 'Hide details' : 'Show details'; const summaryLineHtml = `
${earnSummary}${balanceText}
${detailsToggleLabel}
`; // Table if (machines.length === 0) { $container.html(`
No host machines found on this Vast.ai account.
`); return; } const rowsHtml = machines.map(renderMachineRow).join(''); const tableHtml = ` ${summaryLineHtml} ${rowsHtml}
DEVICE STATUS RATE TEMP RELIABILITY UTILIZATION
`; $container.html(tableHtml); if (data.warning) { $container.prepend(`
${escapeHtml(data.warning)}
`); } // Toggling details is pure local state. Re-render from the payload we // already have instead of refetching, which also avoids the in-flight // isFetching guard swallowing the click. $('#vast_toggle_details').off('click').on('click', function (e) { e.preventDefault(); showHardwareDetails = !showHardwareDetails; if (lastData) renderTile(lastData); }); } /** * Main refresh and render */ window.vastai_refresh = function (force = false) { if (isFetching) return; isFetching = true; const $icon = $('#vast_refresh_icon'); const $container = $('#vast_widget_container'); const $subtitle = $('#vast_subtitle'); if ($icon.length) $icon.addClass('spinning'); const url = '/plugins/vastai/include/getvaststatus.php' + (force ? '?force=1' : ''); $.ajax({ url: url, type: 'GET', dataType: 'json', cache: false, timeout: 12000, success: function (data) { if ($icon.length) $icon.removeClass('spinning'); isFetching = false; if (!data || !data.success) { if (data && data.not_configured) { $subtitle.text('Not Configured'); $container.html(`
${escapeHtml(data.error || 'Please configure your Vast.ai API Key.')}

Go to Vast.ai Settings
`); return; } $subtitle.text('Connection Error'); $container.html(`
${escapeHtml(data ? data.error : 'Failed to connect to Vast.ai API.')}

Retry Connection
`); return; } lastData = data; renderTile(data); }, error: function (xhr, status, err) { if ($icon.length) $icon.removeClass('spinning'); isFetching = false; $subtitle.text('Error'); $container.html(`
Failed to connect to local Vast.ai service (${escapeHtml(status)}).

Retry
`); } }); }; function setupPolling(intervalSec) { if (pollTimer) { clearInterval(pollTimer); pollTimer = null; } const sec = parseInt(intervalSec, 10); if (!isNaN(sec) && sec > 0) { pollTimer = setInterval(function () { if (!document.hidden) { window.vastai_refresh(false); } }, sec * 1000); } } $(function () { const $tile = $('#vast_tile'); if (!$tile.length) return; const initialInterval = $tile.data('interval') || 30; $('#vast_int').on('change', function () { setupPolling($(this).val()); }); $('#vast_btn_refresh').on('click', function (e) { e.preventDefault(); window.vastai_refresh(true); }); setupPolling(initialInterval); window.vastai_refresh(false); }); })(); ]]>
echo "" echo "----------------------------------------------------" echo " &name; has been installed successfully! " echo " Version: &version; " echo "----------------------------------------------------" echo " Next step: Navigate to Settings -> Utilities -> " echo " Vast.ai Monitor to enter your Vast.ai API Key. " echo "----------------------------------------------------" echo "" echo "Removing &name;..." rm -rf &emhttp; rm -f /tmp/vastai_cache.json* if [ -f &plugin;/&name;.cfg ]; then sed -i 's|^API_KEY=.*|API_KEY=""|' &plugin;/&name;.cfg echo "Vast.ai API key scrubbed from &plugin;/&name;.cfg" fi echo "&name; has been removed."