Misc improvements
- Renamed the state file from `fresh.yml` to `.fresh.yml`. - Added option `--state` to override the state file name. - Renamed the lock file from `fresh.lock` to `.fresh.lock`. - Added option `--lockfile` to override lockfile file name.
This commit is contained in:
parent
702cc3101e
commit
214db1cee3
29
CHANGES
Normal file
29
CHANGES
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
**0.1.1**
|
||||||
|
|
||||||
|
- Moved the logic from the entrypoint script to its own class.
|
||||||
|
- Added locking (though `fresh.lock` lockfile) to prevent multiple instances.
|
||||||
|
- Added `--after` hook to invoke script after update.
|
||||||
|
- Disabled automatic flushing of the state to disk; --check will no longer update
|
||||||
|
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.
|
||||||
|
|
||||||
|
**0.1.3**
|
||||||
|
|
||||||
|
- Added a `--before` script hook, to complement the `--after` hook.
|
||||||
|
- Hooks now invoked both before and after deploy.
|
||||||
|
|
||||||
|
**0.1.4**
|
||||||
|
|
||||||
|
- Renamed the state file from `fresh.yml` to `.fresh.yml`.
|
||||||
|
- Added option `--state` to override the state file name.
|
||||||
|
- Renamed the lock file from `fresh.lock` to `.fresh.lock`.
|
||||||
|
- Added option `--lockfile` to override lockfile file name.
|
||||||
|
|
51
README.md
51
README.md
@ -14,19 +14,24 @@ it can do a combination of things:
|
|||||||
Fresh is designed to be invoked using cron or systemd timers, and as such provides
|
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.
|
a light-weight easy-to-use alternative to more complex toolkits.
|
||||||
|
|
||||||
## Building
|
## How to install
|
||||||
|
|
||||||
Build using NoccyLabs Pharlite, included in the tools directory. Don't forget to run
|
Fresh requires **PHP 8.0** or later.
|
||||||
composer to install dependencies first.
|
|
||||||
|
|
||||||
$ composer install
|
|
||||||
$ tools/pharlite
|
|
||||||
|
|
||||||
## Installing
|
|
||||||
|
|
||||||
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`.
|
||||||
You can grab it at [https://dev.noccylabs.info/noccy/fresh/releases](https://dev.noccylabs.info/noccy/fresh/releases).
|
You can grab it at [https://dev.noccylabs.info/noccy/fresh/releases](https://dev.noccylabs.info/noccy/fresh/releases).
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
Build using NoccyLabs Pharlite, included in the tools directory. Don't forget to run
|
||||||
|
composer to install dependencies first. In order to properly generate or update the
|
||||||
|
version file, use the `build.sh` script:
|
||||||
|
|
||||||
|
$ composer install
|
||||||
|
$ tools/build.sh
|
||||||
|
|
||||||
|
The generated .phar can be found as `fresh.phar` and `dist/fresh-VERSION.phar`.
|
||||||
|
|
||||||
## 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
|
||||||
@ -50,6 +55,9 @@ Check a specific image:
|
|||||||
|
|
||||||
For all available options, use the `--help` flag.
|
For all available options, use the `--help` flag.
|
||||||
|
|
||||||
|
Some of the options can be read from environment variables, for example `FRESH_AFER`
|
||||||
|
or `FRESH_SLACK`. See `--help` for supported variables.
|
||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
|
|
||||||
- Only checks authenticated registries for new versions. But if you are using
|
- Only checks authenticated registries for new versions. But if you are using
|
||||||
@ -66,29 +74,8 @@ For all available options, use the `--help` flag.
|
|||||||
- **How do I notify a Mattermost webhook?** Mattermost webhooks are compatible with
|
- **How do I notify a Mattermost webhook?** Mattermost webhooks are compatible with
|
||||||
Slack webhooks, so simply use the `--slack` flag.
|
Slack webhooks, so simply use the `--slack` flag.
|
||||||
|
|
||||||
## Changes
|
|
||||||
|
|
||||||
**0.1.1**
|
|
||||||
|
|
||||||
- Moved the logic from the entrypoint script to its own class.
|
|
||||||
- Added locking (though `fresh.lock` lockfile) to prevent multiple instances.
|
|
||||||
- Added `--after` hook to invoke script after update.
|
|
||||||
- Disabled automatic flushing of the state to disk; --check will no longer update
|
|
||||||
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.
|
|
||||||
|
|
||||||
**0.1.3**
|
|
||||||
|
|
||||||
- Added a `--before` script hook, to complement the `--after` hook.
|
|
||||||
- Hooks now invoked both before and after deploy.
|
|
||||||
|
|
||||||
## Thank you?
|
## Thank you?
|
||||||
|
|
||||||
You can show your appreciation for the time and sweat you have saved through
|
You can show your appreciation by sending me a donation via Paypal.me:
|
||||||
Paypal.me: [https://paypal.me/noccy](paypal.me/noccy).
|
[https://paypal.me/noccy](paypal.me/noccy).
|
||||||
|
|
||||||
|
@ -2,6 +2,25 @@
|
|||||||
|
|
||||||
namespace NoccyLabs\FreshDocker;
|
namespace NoccyLabs\FreshDocker;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fresh.phar
|
||||||
|
Copyright (C) 2022 NoccyLabs
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
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;
|
||||||
@ -16,6 +35,11 @@ use NoccyLabs\FreshDocker\State\Lockfile;
|
|||||||
|
|
||||||
class Refresher
|
class Refresher
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Map for determining options from command line and environment. Each item
|
||||||
|
* has the format:
|
||||||
|
* name => [ short, long, description, [envvar, [default]]]
|
||||||
|
*/
|
||||||
private static array $optionsMap = [
|
private static array $optionsMap = [
|
||||||
'General' => [
|
'General' => [
|
||||||
'help' => [ 'h', 'help', "Show this help" ],
|
'help' => [ 'h', 'help', "Show this help" ],
|
||||||
@ -26,7 +50,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 ],
|
'write-state' => [ 'w', 'write-state', "Always write updated state (only useful with --check)", null, 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" ],
|
||||||
@ -36,10 +60,16 @@ class Refresher
|
|||||||
'Config' => [
|
'Config' => [
|
||||||
'config' => [ 'c:', 'config:', "Use custom configuration file", "FRESH_CONFIG" ],
|
'config' => [ 'c:', 'config:', "Use custom configuration file", "FRESH_CONFIG" ],
|
||||||
'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" ],
|
||||||
|
'state' => [ 's:', 'state:', "Override the state file name", "FRESH_STATE", ".fresh.yml" ],
|
||||||
|
'lockfile' => [ 'l:', 'lockfile:', "Override the lockfile file name", "FRESH_LOCKFILE", ".fresh.lock" ],
|
||||||
'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" ],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
private static $StateFileName = ".fresh.yml";
|
||||||
|
private static $LockFileName = ".fresh.lock";
|
||||||
|
|
||||||
|
/** @var array The parsed options */
|
||||||
private array $options = [];
|
private array $options = [];
|
||||||
|
|
||||||
/** @var HookInterface[] The hooks to invoke */
|
/** @var HookInterface[] The hooks to invoke */
|
||||||
@ -112,6 +142,11 @@ class Refresher
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the usage info (from --help or -h)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
public function printUsage()
|
public function printUsage()
|
||||||
{
|
{
|
||||||
$tty = posix_isatty(STDOUT);
|
$tty = posix_isatty(STDOUT);
|
||||||
@ -186,11 +221,13 @@ class Refresher
|
|||||||
exit(($updated === null) ? 0 : 1);
|
exit(($updated === null) ? 0 : 1);
|
||||||
|
|
||||||
} catch (\Throwable $t) {
|
} catch (\Throwable $t) {
|
||||||
|
|
||||||
fprintf(STDERR, "fatal: %s (%s#%d)\n", $t->getMessage(), $t->getFile(), $t->getLine());
|
fprintf(STDERR, "fatal: %s (%s#%d)\n", $t->getMessage(), $t->getFile(), $t->getLine());
|
||||||
if (!$this->options['verbose']) {
|
if (!$this->options['verbose']) {
|
||||||
fprintf(STDERR, $this->log->asString()."\n");
|
fprintf(STDERR, $this->log->asString()."\n");
|
||||||
}
|
}
|
||||||
exit(2);
|
exit(2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -210,8 +247,14 @@ class Refresher
|
|||||||
$this->log->append("Working dir: ".$this->path);
|
$this->log->append("Working dir: ".$this->path);
|
||||||
chdir($this->path);
|
chdir($this->path);
|
||||||
|
|
||||||
$this->state = new PersistentState($this->path . "/fresh.yml");
|
$statefile = $this->options['state'];
|
||||||
$this->lockfile = new Lockfile($this->path . "/fresh.lock");
|
if (!str_starts_with($statefile,'/')) $statefile = $this->path . "/" . $statefile;
|
||||||
|
|
||||||
|
$lockfile = $this->options['lockfile'];
|
||||||
|
if (!str_starts_with($lockfile,'/')) $lockfile = $this->path . "/" . $lockfile;
|
||||||
|
|
||||||
|
$this->state = new PersistentState($statefile); // $this->path . "/" . self::$StateFileName);
|
||||||
|
$this->lockfile = new Lockfile($lockfile); // $this->path . "/" . self::$LockFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -224,7 +267,7 @@ class Refresher
|
|||||||
case 'auto':
|
case 'auto':
|
||||||
case 'basic':
|
case 'basic':
|
||||||
$this->credentialsLoader = new BasicCredentialsLoader();
|
$this->credentialsLoader = new BasicCredentialsLoader();
|
||||||
$this->log->append("Using BasicCredentialsLoader for credentials");
|
$this->log->append("Using BasicCredentialsLoader");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fwrite(STDERR, "error: Invalid credentials loader type\n");
|
fwrite(STDERR, "error: Invalid credentials loader type\n");
|
||||||
|
20
tools/build.sh
Executable file
20
tools/build.sh
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# chdir into the root from wherever we are
|
||||||
|
cd "$(dirname "$(realpath "$0")")/.."
|
||||||
|
|
||||||
|
# determine the tag and output base
|
||||||
|
TAG="$(git describe --tags)"
|
||||||
|
OUT="dist/fresh-${TAG}"
|
||||||
|
NOW="$(date +"%Y-%m-%d")"
|
||||||
|
|
||||||
|
# create output directory
|
||||||
|
mkdir -p dist
|
||||||
|
|
||||||
|
# update version.php and build thephar
|
||||||
|
echo "<?php define(\"APP_VERSION\", \"${TAG}\"); define(\"BUILD_DATE\", \"${NOW}\");" > src/version.php
|
||||||
|
tools/pharlite
|
||||||
|
|
||||||
|
# copy raw phar into destination
|
||||||
|
cp -v fresh.phar "$OUT.phar"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user