get('/bootstrap.tar.gz'); $response->assertOk(); expect($response->headers->get('Content-Type'))->toBe('application/gzip'); }); /** * Der oberste Eintrag MUSS `bootstrap/` heißen. Die kopierte Zeile packt mit * `tar xz -C /opt/clupilot` aus, und das Skript sucht sich selbst unter * `/opt/clupilot/bootstrap` — ein anderer Name landet daneben, und der Fehler * zeigt sich als „lib/report.sh nicht gefunden" auf einer Maschine, an die man * nur über die Anbieterkonsole kommt. */ it('unpacks to bootstrap/ with the script and its library', function () { $this->get('/bootstrap.tar.gz')->assertOk(); $listing = shell_exec('tar tzf '.escapeshellarg(storage_path('app/bootstrap.tar.gz'))); expect($listing) ->toContain('bootstrap/clupilot-bootstrap.sh') ->toContain('bootstrap/lib/report.sh') ->toContain('bootstrap/lib/proxmox.sh') ->toContain('bootstrap/lib/network.sh') ->toContain('bootstrap/lib/traefik.sh') ->toContain('bootstrap/lib/template.sh') ->toContain('bootstrap/lib/register.sh') ->toContain('bootstrap/assets/docker-compose.yml'); }); /** * Es darf nichts Vertrauliches darin stehen. Alle Geheimnisse reisen in der * Befehlszeile mit, die der Adminbereich genau einmal zeigt. */ it('carries no secrets', function () { $this->get('/bootstrap.tar.gz')->assertOk(); $dir = sys_get_temp_dir().'/bootstrap-pruefung-'.bin2hex(random_bytes(4)); mkdir($dir); shell_exec('tar xzf '.escapeshellarg(storage_path('app/bootstrap.tar.gz')).' -C '.escapeshellarg($dir)); $content = ''; foreach (glob($dir.'/bootstrap/{,lib/,assets/}*', GLOB_BRACE) as $file) { if (is_file($file)) { $content .= file_get_contents($file); } } expect($content)->not->toBeEmpty() ->and($content)->not->toContain(config('app.key')) ->and($content)->not->toContain((string) env('SECRETS_KEY')); shell_exec('rm -rf '.escapeshellarg($dir)); }); /** * Ein Archiv, das einmal gebaut wurde und danach liegen bleibt, ist die Fassung * von dem Tag, an dem jemand zuletzt daran gedacht hat. */ it('rebuilds itself when the script changes', function () { $this->get('/bootstrap.tar.gz')->assertOk(); $first = filemtime(storage_path('app/bootstrap.tar.gz')); // Eine Sekunde zurück, damit die Änderung sichtbar später liegt. touch(storage_path('app/bootstrap.tar.gz'), $first - 10); touch(base_path('deploy/bootstrap/clupilot-bootstrap.sh')); $this->get('/bootstrap.tar.gz')->assertOk(); expect(filemtime(storage_path('app/bootstrap.tar.gz')))->toBeGreaterThan($first - 10); });