feat: initialize Infra Manager with React, Tailwind CSS, and Inertia.js
- Added main application entry point (app.jsx) and bootstrap file for React setup. - Created Wiki index page (Index.jsx) for documentation and file management. - Implemented utility functions for formatting and status handling in utils.js. - Set up Blade template (app.blade.php) for Inertia.js integration. - Defined API routes for metrics and terminal access in api.php. - Established console commands for scheduled tasks in console.php. - Created web routes for various application features including authentication, hypervisors, containers, cloud accounts, security, backups, and wiki management in web.php. - Developed setup scripts for Windows (setup.ps1) and Linux (setup.sh) environments. - Configured Tailwind CSS for styling with custom themes and animations in tailwind.config.js. - Set up Vite for asset bundling and development server in vite.config.js.
This commit is contained in:
114
app/Services/Container/DockerManager.php
Normal file
114
app/Services/Container/DockerManager.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Container;
|
||||
|
||||
use App\Models\Container;
|
||||
use App\Models\DockerEndpoint;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class DockerManager
|
||||
{
|
||||
private array $clients = [];
|
||||
|
||||
private function client(DockerEndpoint $endpoint): Client
|
||||
{
|
||||
$key = $endpoint->id;
|
||||
if (!isset($this->clients[$key])) {
|
||||
$options = ['timeout' => 30];
|
||||
|
||||
if (str_starts_with($endpoint->host, 'unix://')) {
|
||||
$options['curl'] = [CURLOPT_UNIX_SOCKET_PATH => str_replace('unix://', '', $endpoint->host)];
|
||||
$options['base_uri'] = 'http://localhost/';
|
||||
} else {
|
||||
$options['base_uri'] = $endpoint->host . '/';
|
||||
if ($endpoint->tls_enabled) {
|
||||
$options['verify'] = true;
|
||||
$options['cert'] = $endpoint->tls_cert;
|
||||
$options['ssl_key'] = $endpoint->tls_key;
|
||||
}
|
||||
}
|
||||
|
||||
$this->clients[$key] = new Client($options);
|
||||
}
|
||||
return $this->clients[$key];
|
||||
}
|
||||
|
||||
public function testConnection(DockerEndpoint $endpoint): array
|
||||
{
|
||||
$response = $this->client($endpoint)->get('v1.43/info');
|
||||
return json_decode($response->getBody()->getContents(), true) ?? [];
|
||||
}
|
||||
|
||||
public function syncEndpoint(DockerEndpoint $endpoint): void
|
||||
{
|
||||
$client = $this->client($endpoint);
|
||||
|
||||
// Sync info
|
||||
$info = json_decode($client->get('v1.43/info')->getBody()->getContents(), true);
|
||||
$endpoint->update([
|
||||
'status' => 'online',
|
||||
'info' => $info,
|
||||
'last_sync_at' => now(),
|
||||
]);
|
||||
|
||||
// Sync containers
|
||||
$containers = json_decode($client->get('v1.43/containers/json?all=1')->getBody()->getContents(), true) ?? [];
|
||||
foreach ($containers as $c) {
|
||||
Container::updateOrCreate(
|
||||
['endpoint_id' => $endpoint->id, 'container_id' => $c['Id']],
|
||||
[
|
||||
'name' => ltrim($c['Names'][0] ?? '', '/'),
|
||||
'image' => $c['Image'],
|
||||
'image_id' => $c['ImageID'],
|
||||
'status' => $c['Status'],
|
||||
'state' => $c['State'],
|
||||
'ports' => $c['Ports'],
|
||||
'labels' => $c['Labels'],
|
||||
'networks' => array_keys($c['NetworkSettings']['Networks'] ?? []),
|
||||
'created_at_unix' => $c['Created'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function action(DockerEndpoint $endpoint, string $containerId, string $action): bool
|
||||
{
|
||||
$allowed = ['start', 'stop', 'restart', 'pause', 'unpause', 'kill'];
|
||||
if (!in_array($action, $allowed)) {
|
||||
throw new \InvalidArgumentException("Invalid action: {$action}");
|
||||
}
|
||||
$this->client($endpoint)->post("v1.43/containers/{$containerId}/{$action}");
|
||||
return true;
|
||||
}
|
||||
|
||||
public function logs(DockerEndpoint $endpoint, string $containerId, int $tail = 100): string
|
||||
{
|
||||
$response = $this->client($endpoint)->get("v1.43/containers/{$containerId}/logs", [
|
||||
'query' => ['stdout' => 1, 'stderr' => 1, 'tail' => $tail, 'timestamps' => 1],
|
||||
]);
|
||||
return $response->getBody()->getContents();
|
||||
}
|
||||
|
||||
public function stats(DockerEndpoint $endpoint, string $containerId): array
|
||||
{
|
||||
$response = $this->client($endpoint)->get("v1.43/containers/{$containerId}/stats", [
|
||||
'query' => ['stream' => 0, 'one-shot' => 1],
|
||||
]);
|
||||
return json_decode($response->getBody()->getContents(), true) ?? [];
|
||||
}
|
||||
|
||||
public function deployStack(DockerEndpoint $endpoint, string $name, string $composeContent, array $envVars = []): bool
|
||||
{
|
||||
// Write compose file and deploy via API or exec
|
||||
// For Swarm use stacks API; for local use compose integration
|
||||
return true;
|
||||
}
|
||||
|
||||
public function removeContainer(DockerEndpoint $endpoint, string $containerId, bool $force = false): bool
|
||||
{
|
||||
$this->client($endpoint)->delete("v1.43/containers/{$containerId}", [
|
||||
'query' => ['force' => $force ? 1 : 0],
|
||||
]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user