Add upgrade feature
This commit is contained in:
parent
8c8f1a2a46
commit
cd8c20255e
2 changed files with 86 additions and 5 deletions
19
README.md
19
README.md
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
This Icinga/Nagios check plugin permit to check Woodpecker CI instance upgrade status by comparing the local woodpecker-server binary version against the latest stable release.
|
This Icinga/Nagios check plugin permit to check Woodpecker CI instance upgrade status by comparing the local woodpecker-server binary version against the latest stable release.
|
||||||
|
|
||||||
|
This script could also be used to easily upgrade your installation. It could automatically:
|
||||||
|
|
||||||
|
- Download latest release asset matching to your already installed woodpecker packages
|
||||||
|
- Install corresponding packages
|
||||||
|
- Restart corresponding active woodpecker services (agent & server). Note: systemd services name must match the woodpecker package name.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -16,17 +22,24 @@ service nagios-nrpe-server reload
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
usage: check_woodpecker_upgrade [-h] [-d] [-p PATH] [-U URL] [--pre-release] [--draft] [-t TIMEOUT]
|
usage: check_woodpecker_upgrade [-h] [-d] [-v] [-p PATH] [-U URL] [--pre-release]
|
||||||
|
[--draft] [-t TIMEOUT] [-u] [-f] [--arch ARCH]
|
||||||
|
|
||||||
options:
|
options:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
-d, --debug
|
-d, --debug
|
||||||
|
-v, --verbose
|
||||||
-p PATH, --path PATH Woodpecker CI bin path
|
-p PATH, --path PATH Woodpecker CI bin path
|
||||||
-U URL, --url URL Woodpecker CI releases URL
|
-U URL, --url URL Woodpecker CI releases URL
|
||||||
--pre-release Allow pre-release (default: only stable release are considered)
|
--pre-release Allow pre-release (default: only stable release are
|
||||||
--draft Allow draft release (default: only stable release are considered)
|
considered)
|
||||||
|
--draft Allow draft release (default: only stable release are
|
||||||
|
considered)
|
||||||
-t TIMEOUT, --timeout TIMEOUT
|
-t TIMEOUT, --timeout TIMEOUT
|
||||||
Specify timeout for HTTP requests (default: 20)
|
Specify timeout for HTTP requests (default: 20)
|
||||||
|
-u, --upgrade Upgrade Woodpecker CI
|
||||||
|
-f, --force Force upgrade Woodpecker CI
|
||||||
|
--arch ARCH System dpkg architecture (default: auto-detect)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Copyright
|
## Copyright
|
||||||
|
|
|
@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
@ -30,6 +31,7 @@ import requests
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
parser.add_argument("-d", "--debug", action="store_true")
|
parser.add_argument("-d", "--debug", action="store_true")
|
||||||
|
parser.add_argument("-v", "--verbose", action="store_true")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-p", "--path", type=str, help="Woodpecker CI bin path", default="woodpecker-server"
|
"-p", "--path", type=str, help="Woodpecker CI bin path", default="woodpecker-server"
|
||||||
)
|
)
|
||||||
|
@ -53,10 +55,15 @@ parser.add_argument(
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-t", "--timeout", type=int, help="Specify timeout for HTTP requests (default: 20)", default=20
|
"-t", "--timeout", type=int, help="Specify timeout for HTTP requests (default: 20)", default=20
|
||||||
)
|
)
|
||||||
|
parser.add_argument("-u", "--upgrade", action="store_true", help="Upgrade Woodpecker CI")
|
||||||
|
parser.add_argument("-f", "--force", action="store_true", help="Force upgrade Woodpecker CI")
|
||||||
|
parser.add_argument("--arch", help="System dpkg architecture (default: auto-detect)")
|
||||||
|
|
||||||
options = parser.parse_args()
|
options = parser.parse_args()
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG if options.debug else logging.WARNING)
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG if options.debug else (logging.INFO if options.verbose else logging.WARNING)
|
||||||
|
)
|
||||||
|
|
||||||
CURRENT = None
|
CURRENT = None
|
||||||
|
|
||||||
|
@ -114,13 +121,74 @@ if LATEST is None:
|
||||||
|
|
||||||
logging.debug("Latest version is %s", LATEST["name"])
|
logging.debug("Latest version is %s", LATEST["name"])
|
||||||
|
|
||||||
if LATEST["name"] == CURRENT:
|
if LATEST["name"] == CURRENT and not (options.upgrade and options.force):
|
||||||
print(
|
print(
|
||||||
f"OK - The latest release of Woodpecker CI is currently used "
|
f"OK - The latest release of Woodpecker CI is currently used "
|
||||||
f"({LATEST['name']}, published on {LATEST['published_at']})"
|
f"({LATEST['name']}, published on {LATEST['published_at']})"
|
||||||
)
|
)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
if options.upgrade:
|
||||||
|
if not options.arch:
|
||||||
|
logging.info("Auto-detect dpkg architecture...")
|
||||||
|
options.arch = (
|
||||||
|
subprocess.check_output(["dpkg-architecture", "--query", "DEB_HOST_ARCH"])
|
||||||
|
.decode("utf8")
|
||||||
|
.strip()
|
||||||
|
)
|
||||||
|
logging.info("Auto-detected dpkg architecture: %s", options.arch)
|
||||||
|
|
||||||
|
logging.info("List installed Woodpecker package...")
|
||||||
|
INSTALLED = (
|
||||||
|
subprocess.check_output(["dpkg-query", "-Wf", "${Package}\\n", "woodpecker-*"])
|
||||||
|
.decode("utf8")
|
||||||
|
.strip()
|
||||||
|
.split("\n")
|
||||||
|
)
|
||||||
|
logging.info("Installed Woodpecker packages: %s", ", ".join(INSTALLED))
|
||||||
|
|
||||||
|
for PACKAGE in INSTALLED:
|
||||||
|
PACKAGE_ASSET = None
|
||||||
|
for asset in LATEST["assets"]:
|
||||||
|
if re.match(
|
||||||
|
r"^" + PACKAGE + r"_" + LATEST["name"] + "_" + options.arch + r"\.deb$",
|
||||||
|
asset["name"],
|
||||||
|
):
|
||||||
|
PACKAGE_ASSET = asset
|
||||||
|
break
|
||||||
|
if not PACKAGE_ASSET:
|
||||||
|
logging.warning("No asset found for package %s", PACKAGE)
|
||||||
|
continue
|
||||||
|
|
||||||
|
PATH = f"/tmp/{PACKAGE_ASSET['name']}"
|
||||||
|
logging.info(
|
||||||
|
"Download package %s %s to %s (%s)",
|
||||||
|
PACKAGE,
|
||||||
|
LATEST["name"],
|
||||||
|
PATH,
|
||||||
|
PACKAGE_ASSET["browser_download_url"],
|
||||||
|
)
|
||||||
|
r = requests.get(PACKAGE_ASSET["browser_download_url"], timeout=options.timeout)
|
||||||
|
with open(PATH, "wb") as fp:
|
||||||
|
fp.write(r.content)
|
||||||
|
|
||||||
|
logging.info("Install package %s %s", PACKAGE, LATEST["name"])
|
||||||
|
subprocess.run(["dpkg", "-i", PATH], check=True)
|
||||||
|
|
||||||
|
logging.info("Remove temporary file")
|
||||||
|
os.remove(PATH)
|
||||||
|
|
||||||
|
STATUS = subprocess.run(
|
||||||
|
["systemctl", "is-active", PACKAGE], check=False, capture_output=True
|
||||||
|
)
|
||||||
|
if STATUS.stdout.decode().strip() == "active":
|
||||||
|
logging.info("Service %s is active, restart it", PACKAGE)
|
||||||
|
subprocess.run(["systemctl", "restart", PACKAGE], check=True)
|
||||||
|
else:
|
||||||
|
logging.info("No service %s is running", PACKAGE)
|
||||||
|
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
print(
|
print(
|
||||||
"WARNING - The version of Woodpecker CI currently used is not the latest "
|
"WARNING - The version of Woodpecker CI currently used is not the latest "
|
||||||
f"('{CURRENT}' vs '{LATEST['name']}', published on {LATEST['published_at']})"
|
f"('{CURRENT}' vs '{LATEST['name']}', published on {LATEST['published_at']})"
|
||||||
|
|
Loading…
Reference in a new issue