currentVersion(); $releaseDirectory = storage_path('app/server-agent/releases/'.$version); $packageDirectory = $releaseDirectory.'/package'; $archiveFilename = "ladill-server-agent-{$version}.tar.gz"; $archivePath = $releaseDirectory.'/'.$archiveFilename; $tarPath = $releaseDirectory."/ladill-server-agent-{$version}.tar"; File::ensureDirectoryExists($packageDirectory); File::ensureDirectoryExists($releaseDirectory); $renderedFiles = [ 'install.sh' => $this->renderInstallScript(), 'ladill-server-agent' => $this->renderAgentScript($version), 'ladill-server-agent.service' => $this->renderTemplate(resource_path('server-agent/ladill-server-agent.service.tpl')), 'manifest.json' => json_encode([ 'name' => 'ladill-server-agent', 'version' => $version, 'built_at' => now()->toIso8601String(), ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)."\n", ]; foreach ($renderedFiles as $filename => $contents) { File::put($packageDirectory.'/'.$filename, $contents); } if (! File::exists($archivePath)) { if (File::exists($tarPath)) { File::delete($tarPath); } try { $phar = new PharData($tarPath); foreach (array_keys($renderedFiles) as $filename) { $phar->addFile($packageDirectory.'/'.$filename, $filename); } $phar->compress(Phar::GZ); unset($phar); } catch (\Throwable $e) { throw new RuntimeException('Unable to build the server agent release archive.', previous: $e); } finally { if (File::exists($tarPath)) { File::delete($tarPath); } } } if (! File::exists($archivePath)) { throw new RuntimeException('The server agent release archive was not created.'); } return [ 'version' => $version, 'archive_path' => $archivePath, 'checksum_sha256' => hash_file('sha256', $archivePath), 'filename' => $archiveFilename, ]; } public function temporaryDownloadUrl(?string $version = null, ?\DateTimeInterface $expiresAt = null): string { $version ??= $this->currentVersion(); $expiresAt ??= now()->addMinutes((int) config('hosting.server_agent.signed_release_ttl_minutes', 10080)); return URL::temporarySignedRoute('server-agent.releases.download', $expiresAt, [ 'version' => $version, ]); } private function renderAgentScript(string $version): string { return str_replace( ['{{AGENT_VERSION}}', '{{HEARTBEAT_INTERVAL_SECONDS}}'], [ $version, (string) config('hosting.server_agent.heartbeat_interval_seconds', 15), ], $this->renderTemplate(resource_path('server-agent/ladill-server-agent.sh.tpl')) ); } private function renderInstallScript(): string { return $this->renderTemplate(resource_path('server-agent/install.sh.tpl')); } private function renderTemplate(string $path): string { $contents = @file_get_contents($path); if ($contents === false) { throw new RuntimeException("Unable to load server agent release template: {$path}"); } return $contents; } }