Bugfixes and improvements

* Implemented the --image option
* Implemented the --write-state option to go with --check
* Fixed bug in Lockfile class
This commit is contained in:
Chris 2022-03-11 01:55:35 +01:00
parent 66abd9d3c5
commit e77e61d0b0
5 changed files with 85 additions and 13 deletions

View File

@ -48,3 +48,9 @@ For all available options, use the `--help` flag.
- Disabled automatic flushing of the state to disk; --check will no longer update - Disabled automatic flushing of the state to disk; --check will no longer update
the state file, but --pull and default update will. the state file, but --pull and default update will.
**0.1.2**
- Fixed a bug in lockfile class preventing release of stale lockfile.
- The `--image` option finally works.
- Added a `--write-state`/`-w` option to write updated hashes to the state file.
- Implemented `--config` and `--config-type`options.

View File

@ -7,6 +7,7 @@ if (file_exists(__DIR__."/../src/version.php")) {
require_once __DIR__."/../src/version.php"; require_once __DIR__."/../src/version.php";
} else { } else {
define("APP_VERSION", "DEV"); define("APP_VERSION", "DEV");
define("BUILD_DATE", "src");
} }
$r = new NoccyLabs\FreshDocker\Refresher(); $r = new NoccyLabs\FreshDocker\Refresher();

View File

@ -0,0 +1,21 @@
<?php
namespace NoccyLabs\FreshDocker\Configuration;
use Symfony\Component\Yaml\Yaml;
class SingleImageConfiguration
{
private $image;
public function __construct(string $image)
{
$this->image = $image;
}
public function getChecks(): array
{
return [ $this->image ];
}
}

View File

@ -5,6 +5,7 @@ namespace NoccyLabs\FreshDocker;
use NoccyLabs\FreshDocker\State\Log; use NoccyLabs\FreshDocker\State\Log;
use NoccyLabs\FreshDocker\Configuration\ComposeConfiguration; use NoccyLabs\FreshDocker\Configuration\ComposeConfiguration;
use NoccyLabs\FreshDocker\Configuration\LocalConfiguration; use NoccyLabs\FreshDocker\Configuration\LocalConfiguration;
use NoccyLabs\FreshDocker\Configuration\SingleImageConfiguration;
use NoccyLabs\FreshDocker\Credentials\BasicCredentialsLoader; use NoccyLabs\FreshDocker\Credentials\BasicCredentialsLoader;
use NoccyLabs\FreshDocker\Credentials\CredentialsLoaderInterface; use NoccyLabs\FreshDocker\Credentials\CredentialsLoaderInterface;
use NoccyLabs\FreshDocker\Hooks\SlackHook; use NoccyLabs\FreshDocker\Hooks\SlackHook;
@ -25,6 +26,7 @@ class Refresher
'pull' => [ null, 'pull', "Only pull if updated, don't up" ], 'pull' => [ null, 'pull', "Only pull if updated, don't up" ],
'check' => [ null, 'check', "Only check for updates, set exit code" ], 'check' => [ null, 'check', "Only check for updates, set exit code" ],
'prune' => [ null, 'prune', "Prune dangling images after pull and up" ], 'prune' => [ null, 'prune', "Prune dangling images after pull and up" ],
'write-state' => [ 'w', 'write-state', "Always write updated state (only useful with --check)", false ],
], ],
'Hooks' => [ 'Hooks' => [
'slack' => [ null, 'slack:', "Notify a slack webhook when updating", "FRESH_SLACK" ], 'slack' => [ null, 'slack:', "Notify a slack webhook when updating", "FRESH_SLACK" ],
@ -32,7 +34,7 @@ class Refresher
], ],
'Config' => [ 'Config' => [
'config' => [ 'c:', 'config:', "Use custom configuration file", "FRESH_CONFIG" ], 'config' => [ 'c:', 'config:', "Use custom configuration file", "FRESH_CONFIG" ],
'type' => [ 'C:', 'config-type:', "Configuration type (auto, fresh, compose)", "FRESH_CONFIG_TYPE", "auto" ], 'config-type' => [ 'C:', 'config-type:', "Configuration type (auto, fresh, compose)", "FRESH_CONFIG_TYPE", "auto" ],
'credentials' => [ null, 'credentials:', "Set credentials loader type (auto or basic)", "FRESH_CREDENTIALS", "auto" ], 'credentials' => [ null, 'credentials:', "Set credentials loader type (auto or basic)", "FRESH_CREDENTIALS", "auto" ],
] ]
]; ];
@ -111,8 +113,9 @@ class Refresher
public function printUsage() public function printUsage()
{ {
$tty = posix_isatty(STDOUT);
printf("fresh.phar v%s - (c) 2022, NoccyLabs / GPL v3 or later\n", APP_VERSION); printf("fresh.phar v%s (%s) - (c) 2022, NoccyLabs / GPL v3 or later\n", APP_VERSION, BUILD_DATE);
printf("Check for updates to docker images or compose stacks.\n\n"); printf("Check for updates to docker images or compose stacks.\n\n");
printf("Usage:\n %s [options]\n\n", basename($GLOBALS['argv'][0])); printf("Usage:\n %s [options]\n\n", basename($GLOBALS['argv'][0]));
printf("Options:\n"); printf("Options:\n");
@ -129,10 +132,10 @@ class Refresher
if ($s&&$l) $optkey .= ","; if ($s&&$l) $optkey .= ",";
if ($l) $optkey .= "--" . $l; if ($l) $optkey .= "--" . $l;
if ($h) $optkey .= " VALUE"; if ($h) $optkey .= " VALUE";
printf(" %-25s %s", $optkey, $opt[2]); $out = sprintf(" %-25s %s", $optkey, $opt[2]);
if ($d) printf(" (default: %s)", $d); if ($d) $out.= sprintf(" (default: %s)", $d);
if ($e) printf(" [\$%s]", $e); if ($e) $out.= sprintf(" [\$%s]", $e);
echo "\n"; echo $out . "\n";
} }
} }
printf("\nNote:\n"); printf("\nNote:\n");
@ -163,6 +166,11 @@ class Refresher
// If called with --check, only return exit status // If called with --check, only return exit status
if ($this->options['check']) { if ($this->options['check']) {
if (($updated !== null) && $this->options['write-state']) {
// Flush state if called with -w/--write-state
$this->log->append("Flushing state...");
$this->state->flush();
}
exit(($updated === null) ? 0 : 1); exit(($updated === null) ? 0 : 1);
} }
@ -227,13 +235,49 @@ class Refresher
*/ */
private function setupConfiguration() private function setupConfiguration()
{ {
if ($this->options['image']) {
if (file_exists($this->path."/docker-compose.yml")) { $this->config = new SingleImageConfiguration($this->options['image']);
$this->config = new ComposeConfiguration($this->path."/docker-compose.yml"); return;
} else {
fwrite(STDERR, "error: Couldn't find a supported configuration file\n");
exit(2);
} }
$configType = $this->options['config-type'];
$configFile = $this->options['config'] ? realpath($this->options['config']) : null;
switch ($configType) {
case 'auto':
if ($configFile) {
if (basename($configFile) == "docker-compose.yml") {
$this->log->append("Using configuration file ".$configFile);
$this->config = new ComposeConfiguration($configFile);
return;
}
} else {
if (file_exists($this->path."/docker-compose.yml")) {
$this->log->append("Using configuration file ".$this->path."/docker-compose.yml");
$this->config = new ComposeConfiguration($this->path."/docker-compose.yml");
return;
}
}
break;
case 'compose':
if ($configFile) {
if (basename($configFile) == "docker-compose.yml") {
$this->log->append("Using configuration file ".$configFile);
$this->config = new ComposeConfiguration($configFile);
return;
}
} else {
if (file_exists($this->path."/docker-compose.yml")) {
$this->log->append("Using configuration file ".$this->path."/docker-compose.yml");
$this->config = new ComposeConfiguration($this->path."/docker-compose.yml");
return;
}
}
break;
}
fwrite(STDERR, "error: Couldn't find a supported configuration file\n");
exit(2);
} }
/** /**

View File

@ -17,7 +17,7 @@ class Lockfile
public function lock() public function lock()
{ {
if (file_exists($this->filename)) { if (file_exists($this->filename)) {
if (time() - filemtime($this->filename) < $this-$maxLock) { if (time() - filemtime($this->filename) < $this->maxLock) {
throw new \RuntimeException("Lockfile {$this->filename} already exists"); throw new \RuntimeException("Lockfile {$this->filename} already exists");
} }
} }