The Gate and Key
Project description
Yog
Overview
An opinionated docker-and-ssh-centric declarative system management tool.
pip3 install yog
Features:
- Like puppet or ansible but a lot smaller and focused on docker, files, and cron
- agentless - runs entirely on top of ssh
- entirely defers auth(z/n) to ssh and the remote system's user permissions
Non-features:
- No intentional ipv6 support. I don't have anything against IPv6, but my ISP doesn't give me a v6 address and as such I don't run ipv6 on my lan. So since I can't test it at all, I just kind of disregard it, especially where it lets me make the ipv4 UX better.
Command summary:
yog: Applies configurations to hosts. e.g.yog myhost.mytldapplies the config from./domains/mytld/myhost.yml.yog-repo: Manages a docker repository.yog-repo pushuses the contents of./yog-repo.confto build an image and push it to the configured registry with the configured name and tag.
Example run:
Setup
- Configure docker to listen on localhost's port 4243 (which is the default). See below.
- Use
ssh-copy-idto copy your ssh key to all the servers you wish to manage. You can look into ssh certificates if you want a more general ssh PKI solution. - Configure the target system to allow you to use sudo without a password. [2]
- That's it. You now serve the nameless mist. Do you hear whippoorwills?
Docker port listening setup (step 1)
ssh myhost
sudo systemctl edit docker
And add -H tcp://127.0.0.1:4243 to the command. So for me, that file looks like:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:4243
Yog will apply files before docker containers, so you might also want to add a yog file entry like so:
files:
- src: docker-override.conf
dest: /etc/systemd/system/docker.service.d/override.conf
root: yes
hupcmd: sudo systemctl restart docker
Usage
Yog uses YML files that it calls "necronomicons" for configuration of hosts. It's organized hierarchically so that a necronomicon for "mytld" will be applied to all hosts under that TLD.
Let's learn by example:
Suppose we have a folder, that can be named whatever we want, at ~/projects/my-config. This is the root of a
git repo, and is also the root of our yog configuration. Make this your current working dir, or pass --root-dir.
$ cd ~/projects/my-config
.
├── domains
│ ├── com
│ │ └── example
│ │ └── myhost.yml
│ └── com.yml
└── files
├── example.txt
├── hello_world.html
└── helloworld-nginx.conf
4 directories, 5 files
Files that can be sent to hosts are stored under files.
Host configurations - necronomicons - are stored under domains.
If we want to apply myhost.yml, we run:
yog myhost.example.com
Example output:
$ yog myhost.example.com
[2022-12-26 11:01:52,514] [INFO]: [myhost.example.com]
[2022-12-26 11:01:59,121] [INFO]: [myhost.example.com][files]: OK [hello_world.html]
[2022-12-26 11:01:59,274] [INFO]: [myhost.example.com][files]: OK [helloworld-nginx.conf]
[2022-12-26 11:02:07,117] [INFO]: [myhost.example.com][docker]: OK registry@sha256:8be26f81ffea54106bae012c6f349df70f4d5e7e2ec01b143c46e2c03b9e551d
Necronomicon format
Let's look at a necronomicon.
files:
- src: hello_world.html
dest: /srv/hello_world/hello_world.html
root: yes
- src: helloworld-nginx.conf
dest: /etc/nginx/conf.d/helloworld.conf
root: yes
hupcmd: sudo systemctl restart nginx
docker:
- image: registry
name: my-registry
fingerprint: sha256:8be26f81ffea54106bae012c6f349df70f4d5e7e2ec01b143c46e2c03b9e551d
volumes:
images: /var/lib/registry
ports:
- container: 5000
host: [5000]
env:
REGISTRY_STORAGE_DELETE_ENABLED: true
Files
Files are checked for equality via hash-comparison. I've found this a useful way to manage:
- cron files in /etc/cron.d/
- Root certificates to put in the system trust store[1]
- random config files
Attributes:
src: the source. This is a relative path rooted at thefilesdirectory in the hierarchy. You can use intermediate dirs.dest: the destination filepath on the managed host. This is an absolute path.root: whether tosudoto root for the file put. This mainly picks who owns the file + can access files, but this might have other useful properties for your use case. If set tono, the put operation is run as your ssh user.hupcmd: a command to run after the file is placed. A common thing in ye olde days was to send SIGHUP to a process which would handle it by reloading the config. Commonly nowadays you might be usinghupcmd: sudo systemctl reload nginx
Docker containers
Docker containers are compared on all specified attributes and won't unnecessarily restart containers.
Attributes:
image: the docker repository name. e.g.itzg/minecraft-serverordockerrepo.local:5000/mythingname: the container name.fingerprint: sha digest of the desired version. Tags are bad news bears so we don't support them. This is called fingerprint instead of digest because I didn't know they were called digests when I first coded this and then never changed it once I did.volumes: volumes to attach. see below.ports: ports to open. see below.env: environment variables to set.
Volumes
For volumes, the key is the volume name and the value is the mount point.
For bind mounts, the key is the host path and the value is the container path.
Ports
It's a list of:
container: port/protocol
host: [interface_ip:port, interface_ip:port]
For the container, you can omit the protocol to get tcp by default.
For the host, you can omit the interface ip to get 0.0.0.0 which binds all interfaces.
Examples:
- container: 53/tcp
host: [192.168.1.103:53, 127.0.0.1:53]
- container: 53/udp
host: [192.168.1.103:53, 127.0.0.1:53]
- container: 33200 # tcp is implicit default, this is the same behavior as docker
host: [33200] # binds 0.0.0.0
- container: 3000
host: [8080]
Footnotes
[1] This is one of those things where I feel like you probably shouldn't manage root certs like this but I have yet to regret it? It's not a cryptographic secret, so.
[2] Also something that people say you probably shouldn't do but I've yet to regret. If your user is in the docker group it's basically root anyway from a threat modeling perspective.
yog-repo
Yog also includes a tool for pushing images to your local docker registry. I haven't documented it yet, apologies.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file yog-2.1.2.tar.gz.
File metadata
- Download URL: yog-2.1.2.tar.gz
- Upload date:
- Size: 26.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.9.6 readme-renderer/37.3 requests/2.28.2 requests-toolbelt/0.10.1 urllib3/1.26.14 tqdm/4.64.1 importlib-metadata/6.0.0 keyring/23.13.1 rfc3986/2.0.0 colorama/0.4.6 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a45569a7f61fceb62fb25a06b483a70396493255ecf3da918a454793bbeea8f2
|
|
| MD5 |
d47e3b47a51eb5030d349da045ead534
|
|
| BLAKE2b-256 |
31f2d6f36a70d63549a521b7834f91fc1382e202777a26207d14505abb0e4936
|
File details
Details for the file yog-2.1.2-py3-none-any.whl.
File metadata
- Download URL: yog-2.1.2-py3-none-any.whl
- Upload date:
- Size: 40.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.9.6 readme-renderer/37.3 requests/2.28.2 requests-toolbelt/0.10.1 urllib3/1.26.14 tqdm/4.64.1 importlib-metadata/6.0.0 keyring/23.13.1 rfc3986/2.0.0 colorama/0.4.6 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
916c72d6f5196d98f102c3a414380d3a3f39c52d6ef556ba3960b549c8735df0
|
|
| MD5 |
fdd211eb02cd6915fad2f499a32597ad
|
|
| BLAKE2b-256 |
46efcc33daea7b735b2088f41deb0a39d34f15984629fe81f3fdd329ef30075a
|