Improved hooks and scripts
* Invoke hooks before and after updating * Scripts can now be run --before and --after
This commit is contained in:
parent
e77e61d0b0
commit
35f88303fa
31
README.md
31
README.md
@ -1,7 +1,18 @@
|
|||||||
# Fresh: Keeping your docker stacks up to date
|
# Fresh: Keeping your docker stacks up to date
|
||||||
|
|
||||||
Fresh was written to scratch an itch. It works by querying the respective repositories
|
Fresh was written to scratch an itch. It works by querying the respective repositories
|
||||||
returning
|
for the various manifests in order to determine if the images have been changed. If so
|
||||||
|
it can do a combination of things:
|
||||||
|
|
||||||
|
- Set the exitcode to indicate the freshness, `0` means up-to-date and `1` outdated.
|
||||||
|
- Pull the updated images with docker-compose, and optionally recreate the containers
|
||||||
|
with `docker-compose up`.
|
||||||
|
- Run a script before and after updating, f.ex. to enable maintenance mode or update
|
||||||
|
permission on volumes.
|
||||||
|
- Notify webhooks when updating. Currently only Slack and Mattermost are supported.
|
||||||
|
|
||||||
|
Fresh is designed to be invoked using cron or systemd timers, and as such provides
|
||||||
|
a light-weight easy-to-use alternative to more complex toolkits.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
@ -13,6 +24,8 @@ Build using NoccyLabs Pharlite:
|
|||||||
|
|
||||||
Download the latest version (or build it yourself) and move it into `/usr/bin`.
|
Download the latest version (or build it yourself) and move it into `/usr/bin`.
|
||||||
|
|
||||||
|
Go grab it at [https://dev.noccylabs.info/noccy/fresh/releases](https://dev.noccylabs.info/noccy/fresh/releases)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
To check for updates, pull updated images and recreate any containers defined in the
|
To check for updates, pull updated images and recreate any containers defined in the
|
||||||
@ -20,6 +33,15 @@ To check for updates, pull updated images and recreate any containers defined in
|
|||||||
|
|
||||||
$ fresh.phar
|
$ fresh.phar
|
||||||
|
|
||||||
|
Specify a directory to chdir into; very useful with cron:
|
||||||
|
|
||||||
|
$ fresh.phar --dir /srv/docker/mystack
|
||||||
|
|
||||||
|
To invoke scripts or webhooks:
|
||||||
|
|
||||||
|
$ fresh.phar --before scripts/sitedown.sh --after scripts/siteup.sh \
|
||||||
|
--slack https://my.slack.or/mattermost/webhook
|
||||||
|
|
||||||
For all available options, use the `--help` flag.
|
For all available options, use the `--help` flag.
|
||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
@ -37,6 +59,8 @@ For all available options, use the `--help` flag.
|
|||||||
- **What are these hashes?** Fresh grabs the manifest for the image from the registry
|
- **What are these hashes?** Fresh grabs the manifest for the image from the registry
|
||||||
and proceeds to hash a concatenation of all the various build layer hashes. This
|
and proceeds to hash a concatenation of all the various build layer hashes. This
|
||||||
should mean if the image is new but the layers are the same nothing will be updated.
|
should mean if the image is new but the layers are the same nothing will be updated.
|
||||||
|
- **How do I notify a Mattermost webook?** Mattermost webhooks are compatible with
|
||||||
|
Slack webhooks, so simply use the `--slack` flag.
|
||||||
|
|
||||||
## Changes
|
## Changes
|
||||||
|
|
||||||
@ -54,3 +78,8 @@ For all available options, use the `--help` flag.
|
|||||||
- The `--image` option finally works.
|
- The `--image` option finally works.
|
||||||
- Added a `--write-state`/`-w` option to write updated hashes to the state file.
|
- Added a `--write-state`/`-w` option to write updated hashes to the state file.
|
||||||
- Implemented `--config` and `--config-type`options.
|
- Implemented `--config` and `--config-type`options.
|
||||||
|
|
||||||
|
**0.1.3**
|
||||||
|
|
||||||
|
- Added a `--before` script hook, to complement the `--after` hook.
|
||||||
|
- Hooks now invoked both before and after deploy.
|
||||||
|
@ -30,7 +30,8 @@ class Refresher
|
|||||||
],
|
],
|
||||||
'Hooks' => [
|
'Hooks' => [
|
||||||
'slack' => [ null, 'slack:', "Notify a slack webhook when updating", "FRESH_SLACK" ],
|
'slack' => [ null, 'slack:', "Notify a slack webhook when updating", "FRESH_SLACK" ],
|
||||||
'script' => [ null, 'after:', "Invoke script after updating", "FRESH_AFTER" ],
|
'script-after' => [ null, 'after:', "Invoke script after updating", "FRESH_AFTER" ],
|
||||||
|
'script-before' => [ null, 'before:', "Invoke script before updating", "FRESH_BEFORE" ],
|
||||||
],
|
],
|
||||||
'Config' => [
|
'Config' => [
|
||||||
'config' => [ 'c:', 'config:', "Use custom configuration file", "FRESH_CONFIG" ],
|
'config' => [ 'c:', 'config:', "Use custom configuration file", "FRESH_CONFIG" ],
|
||||||
@ -175,9 +176,11 @@ class Refresher
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($updated !== null) {
|
if ($updated !== null) {
|
||||||
$this->callHooks($updated);
|
$this->callHooks($updated, 'before');
|
||||||
$this->doUpdate($updated);
|
$this->callScript('before');
|
||||||
$this->callScript();
|
$this->doUpdate();
|
||||||
|
$this->callHooks($updated, 'after');
|
||||||
|
$this->callScript('after');
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(($updated === null) ? 0 : 1);
|
exit(($updated === null) ? 0 : 1);
|
||||||
@ -362,13 +365,22 @@ class Refresher
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function callHooks(array $updated)
|
private function callHooks(array $updated, string $event)
|
||||||
{
|
{
|
||||||
$images = [];
|
switch ($event) {
|
||||||
foreach ($updated as $u) {
|
case 'before':
|
||||||
$images[] = sprintf("%s/%s:%s", $u->ref->getRegistry(), $u->ref->getImage(), $u->ref->getTag());
|
$images = [];
|
||||||
|
foreach ($updated as $u) {
|
||||||
|
$images[] = sprintf("%s/%s:%s", $u->ref->getRegistry(), $u->ref->getImage(), $u->ref->getTag());
|
||||||
|
}
|
||||||
|
$msg = "Deploying updated containers:\n* ".join("\n* ", $images);
|
||||||
|
break;
|
||||||
|
case 'after':
|
||||||
|
$msg = "Deploy complete";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
$msg = "Deploying updated containers:\n* ".join("\n* ", $images);
|
|
||||||
|
|
||||||
foreach ($this->hooks as $hook) {
|
foreach ($this->hooks as $hook) {
|
||||||
$hook->sendMessage($msg, []);
|
$hook->sendMessage($msg, []);
|
||||||
@ -376,9 +388,9 @@ class Refresher
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function callScript()
|
private function callScript(string $event)
|
||||||
{
|
{
|
||||||
$script = $this->options['script'];
|
$script = $this->options["script-{$event}"] ?? null;
|
||||||
if ($script) {
|
if ($script) {
|
||||||
$this->exec($script);
|
$this->exec($script);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user