diff --git a/app/Docker/Container.php b/app/Docker/Container.php index 9567366..a46d6ad 100644 --- a/app/Docker/Container.php +++ b/app/Docker/Container.php @@ -7,6 +7,7 @@ use React\Http\Browser; use React\Socket\FixedUriConnector; use React\Socket\UnixConnector; +use function React\Async\await; class Container @@ -18,114 +19,93 @@ class Container public function __construct($id) { $this->id = $id; - $this->connector = new FixedUriConnector( - 'unix:///var/run/docker.sock', - new UnixConnector() - ); - $this->browser = new Browser($this->connector); - + $connection = Docker::connect(); + $this->connector = $connection->connector; + $this->browser = $connection->browser; } public function getId() { return $this->id; } - public function start($context) + public function start() { - $context = $context ?? [ "onSucces" => function() {}, "onError" => function() {}]; try { - $this->browser->post("http://localhost/containers/" . $this->id . "/start", [ "Content-Type" => "text/plain" ]) - ->then(function(ResponseInterface $response) use($context) { - $data = json_decode($response->getBody()); - return $context["onSucces"]($this, $data); - }, function($e) use($context) { - return $context["onError"]($e); - }); + $response = await($this->browser->post(Docker::endpoint("/containers/" . $this->id . "/start"), [ + "Content-Type" => "text/plain" + ])); + return json_decode($response->getBody()); } catch (Exception $e) { - return $context["onError"]($e); + throw $e; } } public function restart($context) { - $context = $context ?? [ "onSucces" => function() {}, "onError" => function() {}]; + $context = $context ?? [ "onSuccess" => function() {}, "onError" => function() {}]; try { - $this->browser->post("http://localhost/containers/" . $this->id . "/restart", [ "Content-Type" => "text/plain" ]) - ->then(function(ResponseInterface $response) use($context) { - $data = json_decode($response->getBody()); - return $context["onSucces"]($this, $data); - }, function($e) use($context) { - return $context["onError"]($e); - }); + $response = await($this->browser->post( + Docker::endpoint("/containers/" . $this->id . "/restart"), + [ "Content-Type" => "text/plain" ] + )); + return json_decode($response->getBody()); } catch (Exception $e) { - return $context["onError"]($e); + throw $e; } } public function stop($context) { - $context = $context ?? [ "onSucces" => function() {}, "onError" => function() {}]; + $context = $context ?? [ "onSuccess" => function() {}, "onError" => function() {}]; try { - $this->browser->post("http://localhost/containers/" . $this->id . "/stop", [ "Content-Type" => "text/plain" ]) - ->then(function(ResponseInterface $response) use($context) { - $data = json_decode($response->getBody()); - return $context["onSucces"]($this, $data); - }, function($e) use($context) { - return $context["onError"]($e); - }); + $response = await($this->browser->post( + Docker::endpoint("/containers/" . $this->id . "/stop"), + [ "Content-Type" => "text/plain" ] + )); + return json_decode($response->getBody()); } catch (Exception $e) { - return $context["onError"]($e); + throw $e; } } public function kill($context) { - $context = $context ?? [ "onSucces" => function() {}, "onError" => function() {}]; + $context = $context ?? [ "onSuccess" => function() {}, "onError" => function() {}]; try { - $this->browser->post("http://localhost/containers/" . $this->id . "/kill", [ "Content-Type" => "text/plain" ]) - ->then(function(ResponseInterface $response) use($context) { - $data = json_decode($response->getBody()); - return $context["onSucces"]($this, $data); - }, function($e) use($context) { - return $context["onError"]($e); - }); + $response = await($this->browser->post( + Docker::endpoint("/containers/" . $this->id . "/kill"), + [ "Content-Type" => "text/plain" ] + )); + return json_decode($response->getBody()); } catch (Exception $e) { - return $context["onError"]($e); + throw $e; } } - public function inspect($context) + public function inspect($size = false) { - $context = $context ?? [ "onSucces" => function() {}, "onError" => function() {}]; try { - $this->browser->post("http://localhost/containers/" . $this->id . "/json?size=" . $context["size"] ?? false, [ "Content-Type" => "text/plain" ]) - ->then(function(ResponseInterface $response) use($context) { - $data = json_decode($response->getBody()); - return $context["onSucces"]($this, $data); - }, function($e) use($context) { - return $context["onError"]($e); - }); + $response = await($this->browser->post( + Docker::endpoint("/containers/" . $this->id . "/json?size=" . $size), + [ "Content-Type" => "text/plain" ] + )); + return json_decode($response->getBody()); } catch (Exception $e) { - return $context["onError"]($e); + throw $e; } } - public static function create($name, $config, $context) + public static function create($name, $config) { - $context = $context ?? [ "onSucces" => function() {}, "onError" => function() {}]; try { - $connector = new FixedUriConnector( - 'unix:///var/run/docker.sock', - new UnixConnector() - ); - $browser = new Browser($connector); - - $browser->post('http://localhost/containers/create?name='. $name, [ "Content-Type" => "application/json" ], json_encode($config)) - ->then(function (ResponseInterface $response) use($context) { - $data = json_decode($response->getBody()); - $container = new Container($data->Id); - return $context["onSucces"]($container); - }, $context["onError"]); + $connection = Docker::connect(); + $response = await($connection->browser->post(Docker::endpoint('/containers/create?name='. $name), + [ "Content-Type" => "application/json" ], + json_encode($config) + )); + $data = json_decode($response->getBody()); + $container = new Container($data->Id); + return $container; } catch (Exception $e) { - return $context["onError"]($e); + throw $e; } } } \ No newline at end of file diff --git a/app/Docker/Docker.php b/app/Docker/Docker.php new file mode 100644 index 0000000..15573e6 --- /dev/null +++ b/app/Docker/Docker.php @@ -0,0 +1,41 @@ + $connector, "browser" => $browser ]; + } + + public static function endpoint($url) + { + return config("docker.endpoint", "http://localhost") . $url; + } + + public static function info() + { + try { + $connection = Docker::connect(); + $response = await($connection->browser->get(Docker::endpoint('/info'))); + return json_decode($response->getBody()); + } catch(Exception $e) { + throw $e; + } + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 2de8ddd..be67af8 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "laravel/framework": "^11.31", "laravel/sanctum": "^4.0", "laravel/tinker": "^2.9", + "react/async": "^4.3", "react/http": "^1.11", "react/react": "^1.0", "tightenco/ziggy": "^2.0" diff --git a/composer.lock b/composer.lock index 6b3bce6..35fa1db 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9552b65f1e10c7a50354cd350b053bde", + "content-hash": "a7a7c377576023e2fad0cc6b3ebfbf0e", "packages": [ { "name": "brick/math", @@ -3540,6 +3540,81 @@ ], "time": "2024-04-27T21:32:50+00:00" }, + { + "name": "react/async", + "version": "v4.3.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/async.git", + "reference": "635d50e30844a484495713e8cb8d9e079c0008a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/async/zipball/635d50e30844a484495713e8cb8d9e079c0008a5", + "reference": "635d50e30844a484495713e8cb8d9e079c0008a5", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.8 || ^1.2.1" + }, + "require-dev": { + "phpstan/phpstan": "1.10.39", + "phpunit/phpunit": "^9.6" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Async\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async utilities and fibers for ReactPHP", + "keywords": [ + "async", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/async/issues", + "source": "https://github.com/reactphp/async/tree/v4.3.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-04T14:40:02+00:00" + }, { "name": "react/cache", "version": "v1.2.0", @@ -9117,12 +9192,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { "php": "^8.2" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/public/img/cover.avif b/public/img/cover.avif new file mode 100644 index 0000000..e4a2f1b Binary files /dev/null and b/public/img/cover.avif differ diff --git a/public/img/cover.jpeg b/public/img/cover.jpeg new file mode 100644 index 0000000..bcf76bf Binary files /dev/null and b/public/img/cover.jpeg differ diff --git a/public/img/logo.svg b/public/img/logo.svg new file mode 100644 index 0000000..3c3be2a --- /dev/null +++ b/public/img/logo.svg @@ -0,0 +1 @@ + diff --git a/resources/css/app.css b/resources/css/app.css index b5c61c9..258b38a 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -1,3 +1,11 @@ @tailwind base; @tailwind components; @tailwind utilities; + + +.fade-in { opacity: 0; animation: fadeIn 1s ease-in forwards; } +.slide-up { transform: translateY(20px); animation: slideUp 1s ease-out forwards; } +.scale-hover:hover { transform: scale(1.05); transition: transform 0.3s ease-in-out; } +@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } +@keyframes slideUp { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } + diff --git a/resources/js/Components/DropdownLink.vue b/resources/js/Components/DropdownLink.vue index e5ab50b..d122979 100644 --- a/resources/js/Components/DropdownLink.vue +++ b/resources/js/Components/DropdownLink.vue @@ -12,7 +12,7 @@ defineProps({