## Overview
`nmgr` is a utility program for managing jobs in a Nomad cluster according to certain specific needs and preferences of mine. The type of jobs it is designed to operate on can be gleaned from my [homelab repository](https://github.com/cycneuramus/homelab).
This started as a set of Bash convenience functions which, in time, slowly but surely [threatened](https://github.com/cycneuramus/nmgr/blob/bash-legacy/nmgr) to evolve into an unmaintainable monstrosity. This Python rewrite, consequently, represents a more or less desperate attempt to tame the beast before it would be too late—or perhaps more accurately, a way of trading one set of complexities for another that nevertheless feels a bit more structured and robustly extensible. In any case, it's fun sometimes to seek out a dubious break from the purity of UNIX pipes to get tangled up in some overengineered OOP for a bit instead. Misery needs variety if it is to be enjoyable.
If it's not clear by now, this program should probably not be used without understanding what it does and why it does it.
## Rationale
Consider the following use-cases:
+ You're using something like [Renovate](https://renovatebot.com) to manage updates to container image versions. Now one fine day, a whole bunch of these comes in as a PR, so you merge, pull locally—and then what? Do you manually hunt down all the jobs needing to be updated and restart them one by one? Well, now you can do this instead:
`nmgr reconcile all`
Or, if you still would like to preserve some manual control:
`nmgr reconcile my-specific-job`
Also, just for fun, you might first want to compare a job's currently running images against those in its specification:
```
$ nmgr image forgejo
Live images:
forgejo = "codeberg.org/forgejo/forgejo:9.0.3-rootless"
valkey = "docker.io/valkey/valkey:7.2-alpine"
Spec images:
forgejo = "codeberg.org/forgejo/forgejo:10.0.0-rootless"
valkey = "docker.io/valkey/valkey:8.0-alpine"
```
---
+ You're about to perform a server upgrade that requires a restart. Instead of manually coddling every one of those 50+ running jobs first, it sure would be handy to be able to do this:
```
nmgr down all
sudo apt update && sudo apt upgrade
sudo reboot now
[...]
nmgr up all
```
---
+ Nextcloud's PHP spaghetti has decided to crap the bed, and you have no choice but to start tailing the logs. "What's the syntax again? `nomad logs -f -job nextcloud`? Wait, no, that errors out. Oh, that's right: I have to specify a 'task' to get the logs from. But what did I name the Nextcloud job tasks? I better check the job specification..." *No!* Stop right there.
```
$ nmgr logs nextcloud
Tasks for job nextcloud:
1. server
2. cron
3. redis
4. push
5. collabora
Select a task (number):
```
And off you go.
---
+ At random parts of the day, your heart will sink when you suddenly remember you probably still have some jobs running with a `latest` image tag. After some time, you have had enough of these crises of conscience, so you roll up your sleeves, `ssh` into the server, and–what's that? You were going to hunt down all those image specifications *manually*? Don't be silly:
`nmgr find :latest`
---
+ You're about to upgrade or otherwise mess with, say, a NAS on which a host of currently running jobs depend. Do you now wade through each and every job specification to remind yourself which jobs you would need to stop before making your changes? Instead, you could do this:
`nmgr down nas`
And then, after you're done messing with the NAS:
`nmgr up nas`
You could do the same thing for jobs that depend on e.g. a database job (`nmgr {up,down} db`), a [JuiceFS](https://juicefs.com) mount (`nmgr {up,down} jfs`), and so forth.
---
+ Before blindly tearing down a bunch of jobs as in the example above, you would like to know exactly which jobs are going to be impacted. Hence, nervous Nellie that you are, you run:
`nmgr list nas`
Or, if you could muster up just a bit more courage, you might perform a dry-run:
`nmgr -n down nas`
---
**NOTE**: Some of these examples make use of custom target filters (`nas`, `jfs`, `db`). These can be defined in the [configuration file](https://github.com/cycneuramus/nmgr/blob/master/nmgr/data/config.toml) that will be generated on first run.
## Installation
`nmgr` is packaged on [PyPi](https://pypi.org/project/nmgr) and can be installed using, for example, [`pipx`](https://pipx.pypa.io/stable/):
`pipx install nmgr`
## Usage
```
usage: nmgr [options] [action] [target]
Nomad job manager
positional arguments:
action up, down, find, list, image, logs, reconcile
target infra, services, all, a custom filter, a specific job name, or a string (for "find")
options:
-h, --help show this help message and exit
-c, --config CONFIG path to config file (default: /home/<user>/.config/nmgr/config.toml)
-n, --dry-run dry-run mode
-d, --detach start jobs in detached mode
-v, --verbose verbose output
--completion install autocompletion for Bash and exit
```
Raw data
{
"_id": null,
"home_page": "https://github.com/cycneuramus/nmgr",
"name": "nmgr",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "nomad",
"author": "cycneuramus",
"author_email": "56681631+cycneuramus@users.noreply.github.com",
"download_url": "https://files.pythonhosted.org/packages/c1/5d/45d0fb67dbf5ca9be9bd7a8168506831c5ef372e53253bb325e7be535692/nmgr-0.1.0.tar.gz",
"platform": null,
"description": "## Overview\n\n`nmgr` is a utility program for managing jobs in a Nomad cluster according to certain specific needs and preferences of mine. The type of jobs it is designed to operate on can be gleaned from my [homelab repository](https://github.com/cycneuramus/homelab).\n\nThis started as a set of Bash convenience functions which, in time, slowly but surely [threatened](https://github.com/cycneuramus/nmgr/blob/bash-legacy/nmgr) to evolve into an unmaintainable monstrosity. This Python rewrite, consequently, represents a more or less desperate attempt to tame the beast before it would be too late\u2014or perhaps more accurately, a way of trading one set of complexities for another that nevertheless feels a bit more structured and robustly extensible. In any case, it's fun sometimes to seek out a dubious break from the purity of UNIX pipes to get tangled up in some overengineered OOP for a bit instead. Misery needs variety if it is to be enjoyable.\n\nIf it's not clear by now, this program should probably not be used without understanding what it does and why it does it.\n\n## Rationale\n\nConsider the following use-cases:\n\n+ You're using something like [Renovate](https://renovatebot.com) to manage updates to container image versions. Now one fine day, a whole bunch of these comes in as a PR, so you merge, pull locally\u2014and then what? Do you manually hunt down all the jobs needing to be updated and restart them one by one? Well, now you can do this instead:\n\n `nmgr reconcile all`\n\n Or, if you still would like to preserve some manual control:\n\n `nmgr reconcile my-specific-job`\n\n Also, just for fun, you might first want to compare a job's currently running images against those in its specification:\n\n ```\n $ nmgr image forgejo\n Live images:\n forgejo = \"codeberg.org/forgejo/forgejo:9.0.3-rootless\"\n valkey = \"docker.io/valkey/valkey:7.2-alpine\"\n\n Spec images:\n forgejo = \"codeberg.org/forgejo/forgejo:10.0.0-rootless\"\n valkey = \"docker.io/valkey/valkey:8.0-alpine\"\n ```\n\n---\n\n+ You're about to perform a server upgrade that requires a restart. Instead of manually coddling every one of those 50+ running jobs first, it sure would be handy to be able to do this:\n\n ```\n nmgr down all\n sudo apt update && sudo apt upgrade\n sudo reboot now\n\n [...]\n\n nmgr up all\n ```\n\n---\n\n+ Nextcloud's PHP spaghetti has decided to crap the bed, and you have no choice but to start tailing the logs. \"What's the syntax again? `nomad logs -f -job nextcloud`? Wait, no, that errors out. Oh, that's right: I have to specify a 'task' to get the logs from. But what did I name the Nextcloud job tasks? I better check the job specification...\" *No!* Stop right there.\n\n ```\n $ nmgr logs nextcloud\n Tasks for job nextcloud:\n 1. server\n 2. cron\n 3. redis\n 4. push\n 5. collabora\n\n Select a task (number):\n ```\n\n And off you go.\n\n---\n\n+ At random parts of the day, your heart will sink when you suddenly remember you probably still have some jobs running with a `latest` image tag. After some time, you have had enough of these crises of conscience, so you roll up your sleeves, `ssh` into the server, and\u2013what's that? You were going to hunt down all those image specifications *manually*? Don't be silly:\n\n `nmgr find :latest`\n\n---\n\n+ You're about to upgrade or otherwise mess with, say, a NAS on which a host of currently running jobs depend. Do you now wade through each and every job specification to remind yourself which jobs you would need to stop before making your changes? Instead, you could do this:\n\n `nmgr down nas`\n\n And then, after you're done messing with the NAS:\n\n `nmgr up nas`\n\n You could do the same thing for jobs that depend on e.g. a database job (`nmgr {up,down} db`), a [JuiceFS](https://juicefs.com) mount (`nmgr {up,down} jfs`), and so forth.\n\n---\n\n+ Before blindly tearing down a bunch of jobs as in the example above, you would like to know exactly which jobs are going to be impacted. Hence, nervous Nellie that you are, you run:\n\n `nmgr list nas`\n\n Or, if you could muster up just a bit more courage, you might perform a dry-run:\n\n `nmgr -n down nas`\n\n---\n\n**NOTE**: Some of these examples make use of custom target filters (`nas`, `jfs`, `db`). These can be defined in the [configuration file](https://github.com/cycneuramus/nmgr/blob/master/nmgr/data/config.toml) that will be generated on first run.\n\n## Installation\n\n`nmgr` is packaged on [PyPi](https://pypi.org/project/nmgr) and can be installed using, for example, [`pipx`](https://pipx.pypa.io/stable/):\n\n`pipx install nmgr`\n\n## Usage\n\n```\nusage: nmgr [options] [action] [target]\n\nNomad job manager\n\npositional arguments:\n action up, down, find, list, image, logs, reconcile\n target infra, services, all, a custom filter, a specific job name, or a string (for \"find\")\n\noptions:\n -h, --help show this help message and exit\n -c, --config CONFIG path to config file (default: /home/<user>/.config/nmgr/config.toml)\n -n, --dry-run dry-run mode\n -d, --detach start jobs in detached mode\n -v, --verbose verbose output\n --completion install autocompletion for Bash and exit\n```\n",
"bugtrack_url": null,
"license": "GPL-3.0-only",
"summary": "Nomad job management tool",
"version": "0.1.0",
"project_urls": {
"Homepage": "https://github.com/cycneuramus/nmgr",
"Repository": "https://github.com/cycneuramus/nmgr"
},
"split_keywords": [
"nomad"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6e9f0b62c92f6fbf79832ee6e8b3df816c082b78f3349161bdf50f931e33b78c",
"md5": "fa7908229e3b5a4cc5f796a50a626f1a",
"sha256": "2210b1d1e590f533b621b4e73c344f0df4643eb1212b6eff2670073cf2987e9f"
},
"downloads": -1,
"filename": "nmgr-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "fa7908229e3b5a4cc5f796a50a626f1a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 25145,
"upload_time": "2025-02-14T14:43:22",
"upload_time_iso_8601": "2025-02-14T14:43:22.430053Z",
"url": "https://files.pythonhosted.org/packages/6e/9f/0b62c92f6fbf79832ee6e8b3df816c082b78f3349161bdf50f931e33b78c/nmgr-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c15d45d0fb67dbf5ca9be9bd7a8168506831c5ef372e53253bb325e7be535692",
"md5": "bf75e307980ff1be4dfba91702517849",
"sha256": "8eb1a1a5c8e8164f71d9c6380741d072a72218f4445ab31cc6252553ba8551a7"
},
"downloads": -1,
"filename": "nmgr-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "bf75e307980ff1be4dfba91702517849",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 24285,
"upload_time": "2025-02-14T14:43:24",
"upload_time_iso_8601": "2025-02-14T14:43:24.213652Z",
"url": "https://files.pythonhosted.org/packages/c1/5d/45d0fb67dbf5ca9be9bd7a8168506831c5ef372e53253bb325e7be535692/nmgr-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-14 14:43:24",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "cycneuramus",
"github_project": "nmgr",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "nmgr"
}