From caf0f55219f4c6ac47f256072296348e007a87a5 Mon Sep 17 00:00:00 2001 From: "kirill.labutin" Date: Tue, 19 Aug 2025 12:42:16 +0300 Subject: [PATCH] Initial commit --- .gitignore | 1 + composer.json | 2 + docker-decompose.iml | 8 +++ docker-decompose.php | 152 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+) create mode 100644 .gitignore create mode 100644 composer.json create mode 100644 docker-decompose.iml create mode 100644 docker-decompose.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85e7c1d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.idea/ diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/composer.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/docker-decompose.iml b/docker-decompose.iml new file mode 100644 index 0000000..80cc739 --- /dev/null +++ b/docker-decompose.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/docker-decompose.php b/docker-decompose.php new file mode 100644 index 0000000..239428e --- /dev/null +++ b/docker-decompose.php @@ -0,0 +1,152 @@ +#!/usr/bin/php +checkBinary(); + $this->root = getcwd(); + println("Working in directory: " . $this->root); + + $this->checkComposeFile(); + + $existing = false; + + if ($this->checkRunningContainers()) { + $existing = true; + println("There are existing containers. Do you want to export them? [y/n]"); + + if (cin() != "y") { + println("Canceling..."); + return; + } + } else { + $this->startContainers(); + } + + if ($this->checkRunningContainers() && count($this->containerNames) > 0) { + println("Exporting " . count($this->containerNames) . " images..."); + foreach ($this->containerNames as $name) { + $this->exportContainer($name); + } + } else { + throw new RuntimeException("Something went wrong. There is no containers detected."); + } + + if($existing){ + println("Do you want to remove running containers? [y/n]"); + if (cin() == "y") { + $this->removeContainers(); + } + }else{ + $this->removeContainers(); + } + + + + println("Done"); + } + + function startContainers() + { + println("Starting containers..."); + println(shell_exec("docker-compose up -d")); + } + + function exportContainer($name) + { + println("Creating image of " . $name . "..."); + println(shell_exec("docker commit " . $name . " " . $name)); + println("Exporting image to file..."); + println(shell_exec("docker save -o " . $name . ".tar " . $name . ":latest")); + println("Removing image..."); + println(shell_exec("docker image rm " . $name . ":latest")); + + if (!file_exists($name . ".tar")) { + throw new RuntimeException("Unable to find output image file"); + } + } + + function removeContainers() + { + println("Removing containers..."); + println(shell_exec("docker-compose down -v --remove-orphans")); + } + + function checkBinary() + { + $compose = @shell_exec("which " . COMPOSE_BINARY); + + if (!file_exists(trim($compose))) { + throw new RuntimeException(COMPOSE_BINARY . " binary was not found in PATH"); + } + } + + function checkComposeFile() + { + if (!file_exists($this->root . "/" . COMPOSE_FILE)) { + throw new RuntimeException(COMPOSE_FILE . " was not found in " . $this->root); + } + } + + function checkRunningContainers(): bool + { + $running_data = @shell_exec("docker-compose ps"); + $running_data = explode("\n", trim($running_data)); + + if (count($running_data) > 2) { + $this->containerNames = []; + for ($i = 2; $i < count($running_data); $i++) { + $parts = explode(" ", $running_data[$i], 2); + $this->containerNames[] = $parts[0]; + } + foreach ($running_data as $row) { + println(trim($row)); + } + return true; + } + + return false; + } + + private $containerNames = []; +} + + +try { + $app = new DecomposerApp(); + + +} catch (Exception $e) { + echo "Error: " . $e->getMessage() . "\n"; + exit(1); +} finally { + echo "\n"; +} +