misterio 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- misterio-0.1.0/LICENSE +21 -0
- misterio-0.1.0/PKG-INFO +103 -0
- misterio-0.1.0/README.md +89 -0
- misterio-0.1.0/pyproject.toml +33 -0
- misterio-0.1.0/src/misterio/__init__.py +0 -0
- misterio-0.1.0/src/misterio/misterio.py +119 -0
misterio-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Giovanni Giorgi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
misterio-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: misterio
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: misterio CLI
|
|
5
|
+
Author-email: Giovanni Giorgi <jj@gioorgi.com>
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: click>=8.2.1
|
|
13
|
+
|
|
14
|
+
# Misterio: so what?
|
|
15
|
+
Docker-compose based Ansible/SaltStack/NameYour *minimalistic alternative*.
|
|
16
|
+
<img align="right" src="https://gioorgi.com/wp-content/uploads/2020/07/misterio-300x170.png" alt="Mysterio Marvel" >
|
|
17
|
+
It is super-easy to use.
|
|
18
|
+
|
|
19
|
+
*Cool!* The new python version is easier to use and understand.
|
|
20
|
+
|
|
21
|
+
Misterio is a python command you can use to "apply" a set of roles to a infinite numbers of hosts.
|
|
22
|
+
Less then 120 lines of python code HELP INCLUDED (sorry Ansible :)
|
|
23
|
+
|
|
24
|
+
Misterio is able to manage a set of compose target as an one, appling status changes easily.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Why?
|
|
28
|
+
1. The only dependency is a recent version of `docker` CE (on target hosts) and `python` 3 (on misterio host).
|
|
29
|
+
2. It does not rely on docker swarm or on K8s. It can run even on ultra-small nano containers on Amazon, provided you have little swap (tested)
|
|
30
|
+
3. It is agent-less. It depends only on `docker daemon` on the target. Docker communication is done via ssh and can be further configured via the .ssh/config file (for instance to setup keys, tunneling, etc)
|
|
31
|
+
4. Everything must be versioned to work: you cannot easily "forget" something on your local machine.
|
|
32
|
+
|
|
33
|
+
# How
|
|
34
|
+
For every hostname, define a directory inside `hosts/`
|
|
35
|
+
Put in it an `env` file based on this syntax:
|
|
36
|
+
|
|
37
|
+
<rolename>[@inst].env
|
|
38
|
+
|
|
39
|
+
where `@inst` is OPTIONAL and can be used to have multiple instances on the same machine.
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# The magic
|
|
43
|
+
For every role on the target machine misterio will:
|
|
44
|
+
1. copy the correct `env` file.
|
|
45
|
+
2. pass the command you provide to `docker-compose`
|
|
46
|
+
3. fail fast or loop
|
|
47
|
+
|
|
48
|
+
The "apply" pseudo-command will do a `build` and `up` in one step
|
|
49
|
+
|
|
50
|
+
*NEW!* You can use the pseudo command --list to get the list of all the roles, and the --single-role option to restrict only to a role.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Distributed
|
|
54
|
+
Because misterio manage the DOCKER_HOST automatically, it is already distributed
|
|
55
|
+
|
|
56
|
+
# Python version
|
|
57
|
+
Install on your virtualenv with
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
python -m venv .venv
|
|
61
|
+
. .venv/bin/activate
|
|
62
|
+
pip install -e .
|
|
63
|
+
misterio --help
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# The Bonus
|
|
69
|
+
Misterio is also a collection of ready-made docker-compose infrastructure you can jump into.
|
|
70
|
+
For instance, jenkins-with-docker show you how to get a dockerized-jenkins with:
|
|
71
|
+
|
|
72
|
+
- self running git server
|
|
73
|
+
- access to docker daemon to self-build stuff using docker plugin
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# Tips
|
|
77
|
+
Under docker for Windows, add
|
|
78
|
+
COMPOSE_CONVERT_WINDOWS_PATHS=1
|
|
79
|
+
to your env path if you plan to bind stuff like
|
|
80
|
+
> /var/run/docker.sock:/var/run/docker.sock
|
|
81
|
+
|
|
82
|
+
This will enable your roles to run on Windows and on Linux dameons seamlessly.
|
|
83
|
+
See https://stackoverflow.com/a/52866439/75540 for more details
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# The Hype
|
|
87
|
+
1. You can add git submodules below `roles/` to link recipes (your personal "ansible galaxy" is... docker hub!)
|
|
88
|
+
2. No complex stuff to learn: it is just DOCKER!
|
|
89
|
+
|
|
90
|
+
# Podman
|
|
91
|
+
|
|
92
|
+
Podman is not tested, and it could require a modification to the way the DOCKER_HOST variable is addressed too. anyway, if you are able to create a pull request with a --podman option, I will be happy to merge it.
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# Other alternative
|
|
97
|
+
https://github.com/piku/piku is an heroku-like alternative, based on python and not requiring docker.
|
|
98
|
+
|
|
99
|
+
# Legacy
|
|
100
|
+
The old misterio bash version can be found under [./old_sh_version](./old_sh_version) folder: it is a 4 years old version, which can still be used if want to further reduce depencencies on misterio controlling host.
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
misterio-0.1.0/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Misterio: so what?
|
|
2
|
+
Docker-compose based Ansible/SaltStack/NameYour *minimalistic alternative*.
|
|
3
|
+
<img align="right" src="https://gioorgi.com/wp-content/uploads/2020/07/misterio-300x170.png" alt="Mysterio Marvel" >
|
|
4
|
+
It is super-easy to use.
|
|
5
|
+
|
|
6
|
+
*Cool!* The new python version is easier to use and understand.
|
|
7
|
+
|
|
8
|
+
Misterio is a python command you can use to "apply" a set of roles to a infinite numbers of hosts.
|
|
9
|
+
Less then 120 lines of python code HELP INCLUDED (sorry Ansible :)
|
|
10
|
+
|
|
11
|
+
Misterio is able to manage a set of compose target as an one, appling status changes easily.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Why?
|
|
15
|
+
1. The only dependency is a recent version of `docker` CE (on target hosts) and `python` 3 (on misterio host).
|
|
16
|
+
2. It does not rely on docker swarm or on K8s. It can run even on ultra-small nano containers on Amazon, provided you have little swap (tested)
|
|
17
|
+
3. It is agent-less. It depends only on `docker daemon` on the target. Docker communication is done via ssh and can be further configured via the .ssh/config file (for instance to setup keys, tunneling, etc)
|
|
18
|
+
4. Everything must be versioned to work: you cannot easily "forget" something on your local machine.
|
|
19
|
+
|
|
20
|
+
# How
|
|
21
|
+
For every hostname, define a directory inside `hosts/`
|
|
22
|
+
Put in it an `env` file based on this syntax:
|
|
23
|
+
|
|
24
|
+
<rolename>[@inst].env
|
|
25
|
+
|
|
26
|
+
where `@inst` is OPTIONAL and can be used to have multiple instances on the same machine.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# The magic
|
|
30
|
+
For every role on the target machine misterio will:
|
|
31
|
+
1. copy the correct `env` file.
|
|
32
|
+
2. pass the command you provide to `docker-compose`
|
|
33
|
+
3. fail fast or loop
|
|
34
|
+
|
|
35
|
+
The "apply" pseudo-command will do a `build` and `up` in one step
|
|
36
|
+
|
|
37
|
+
*NEW!* You can use the pseudo command --list to get the list of all the roles, and the --single-role option to restrict only to a role.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# Distributed
|
|
41
|
+
Because misterio manage the DOCKER_HOST automatically, it is already distributed
|
|
42
|
+
|
|
43
|
+
# Python version
|
|
44
|
+
Install on your virtualenv with
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
python -m venv .venv
|
|
48
|
+
. .venv/bin/activate
|
|
49
|
+
pip install -e .
|
|
50
|
+
misterio --help
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# The Bonus
|
|
56
|
+
Misterio is also a collection of ready-made docker-compose infrastructure you can jump into.
|
|
57
|
+
For instance, jenkins-with-docker show you how to get a dockerized-jenkins with:
|
|
58
|
+
|
|
59
|
+
- self running git server
|
|
60
|
+
- access to docker daemon to self-build stuff using docker plugin
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# Tips
|
|
64
|
+
Under docker for Windows, add
|
|
65
|
+
COMPOSE_CONVERT_WINDOWS_PATHS=1
|
|
66
|
+
to your env path if you plan to bind stuff like
|
|
67
|
+
> /var/run/docker.sock:/var/run/docker.sock
|
|
68
|
+
|
|
69
|
+
This will enable your roles to run on Windows and on Linux dameons seamlessly.
|
|
70
|
+
See https://stackoverflow.com/a/52866439/75540 for more details
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# The Hype
|
|
74
|
+
1. You can add git submodules below `roles/` to link recipes (your personal "ansible galaxy" is... docker hub!)
|
|
75
|
+
2. No complex stuff to learn: it is just DOCKER!
|
|
76
|
+
|
|
77
|
+
# Podman
|
|
78
|
+
|
|
79
|
+
Podman is not tested, and it could require a modification to the way the DOCKER_HOST variable is addressed too. anyway, if you are able to create a pull request with a --podman option, I will be happy to merge it.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# Other alternative
|
|
84
|
+
https://github.com/piku/piku is an heroku-like alternative, based on python and not requiring docker.
|
|
85
|
+
|
|
86
|
+
# Legacy
|
|
87
|
+
The old misterio bash version can be found under [./old_sh_version](./old_sh_version) folder: it is a 4 years old version, which can still be used if want to further reduce depencencies on misterio controlling host.
|
|
88
|
+
|
|
89
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Configuration based on tutorial at
|
|
2
|
+
# https://packaging.python.org/en/latest/tutorials/packaging-projects/
|
|
3
|
+
[project]
|
|
4
|
+
name = "misterio"
|
|
5
|
+
version = "0.1.0"
|
|
6
|
+
description = "misterio CLI"
|
|
7
|
+
authors = [
|
|
8
|
+
{ name="Giovanni Giorgi", email="jj@gioorgi.com" },
|
|
9
|
+
]
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"click>=8.2.1",
|
|
14
|
+
]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
]
|
|
19
|
+
license = "MIT"
|
|
20
|
+
license-files = ["LICEN[CS]E*"]
|
|
21
|
+
|
|
22
|
+
[projects.urls]
|
|
23
|
+
Homepage = "https://github.com/daitangio/misterio"
|
|
24
|
+
Issues = "https://github.com/daitangio/misterio/issues"
|
|
25
|
+
|
|
26
|
+
[project.scripts]
|
|
27
|
+
misterio = "misterio.misterio:misterio"
|
|
28
|
+
|
|
29
|
+
[build-system]
|
|
30
|
+
# Flit Core is a lightweight tool designed to simplify the process of packaging and distributing Python projects
|
|
31
|
+
# following PEP 517
|
|
32
|
+
requires = ["flit_core<4"]
|
|
33
|
+
build-backend = "flit_core.buildapi"
|
|
File without changes
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import os, sys, shutil, subprocess
|
|
2
|
+
import click
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def is_apply(cmdlist):
|
|
6
|
+
if len(cmdlist) == 1:
|
|
7
|
+
if cmdlist[0] == "apply":
|
|
8
|
+
return True
|
|
9
|
+
return False
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def process_role(home, env_full_path, docker_command):
|
|
13
|
+
env_file = os.path.basename(env_full_path)
|
|
14
|
+
if is_apply(docker_command):
|
|
15
|
+
docker_command = ["up", "--build", "-d"]
|
|
16
|
+
if "@" in env_file:
|
|
17
|
+
role_name = env_file.split("@")[0]
|
|
18
|
+
else:
|
|
19
|
+
role_name = env_file.split(".env")[0]
|
|
20
|
+
dirz = os.path.join(home, "roles", role_name)
|
|
21
|
+
full_command = ["docker", "compose"]
|
|
22
|
+
full_command.extend(docker_command)
|
|
23
|
+
docker_host = os.environ["DOCKER_HOST"]
|
|
24
|
+
print(f"{role_name} \t-> {full_command}")
|
|
25
|
+
os.chdir(dirz)
|
|
26
|
+
shutil.copyfile(env_full_path, ".env")
|
|
27
|
+
try:
|
|
28
|
+
subprocess.run(full_command, check=True)
|
|
29
|
+
except subprocess.CalledProcessError as e:
|
|
30
|
+
print(f"{docker_host}::{role_name} Failed with return code {e.returncode}")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@click.command("misterio")
|
|
34
|
+
@click.option(
|
|
35
|
+
"--home",
|
|
36
|
+
envvar="MISTERIO_HOME",
|
|
37
|
+
default=os.getenv("PWD", ""),
|
|
38
|
+
help="Home of hosts and roles folders. Can be set with MISTERIO_HOME",
|
|
39
|
+
)
|
|
40
|
+
@click.option(
|
|
41
|
+
"--misterio-host",
|
|
42
|
+
"-h",
|
|
43
|
+
multiple=True,
|
|
44
|
+
default=None,
|
|
45
|
+
help="Default to single hostname restriction. Can be overriden also with MISTERIO_HOST.",
|
|
46
|
+
)
|
|
47
|
+
@click.option(
|
|
48
|
+
"--list/--no-list",
|
|
49
|
+
"list_flag",
|
|
50
|
+
help="List roles and exits",
|
|
51
|
+
default=False,
|
|
52
|
+
)
|
|
53
|
+
@click.option(
|
|
54
|
+
"--single-role",
|
|
55
|
+
"-r",
|
|
56
|
+
envvar="MISTERIO_SINGLE_ROLE",
|
|
57
|
+
default=None,
|
|
58
|
+
help="Process just one role",
|
|
59
|
+
)
|
|
60
|
+
@click.version_option(version="0.1.0")
|
|
61
|
+
@click.argument("docker_command", nargs=-1, type=str)
|
|
62
|
+
def misterio(home, list_flag, misterio_host, single_role, docker_command):
|
|
63
|
+
"""M I S T E R I O
|
|
64
|
+
docker compose-based alternative to K8s/Ansible/SaltStack
|
|
65
|
+
|
|
66
|
+
By default the system will scan all the hostname inside
|
|
67
|
+
$MISTERIO_HOME/hosts/
|
|
68
|
+
and connect to every of them using DOCKER_HOST=ssh://<hostname> for connection
|
|
69
|
+
|
|
70
|
+
Examples:
|
|
71
|
+
|
|
72
|
+
Ensure everything is configured properly:
|
|
73
|
+
|
|
74
|
+
mistero apply
|
|
75
|
+
|
|
76
|
+
Verify logs of all services to just one server:
|
|
77
|
+
|
|
78
|
+
misterio -h wonderboy -- logs --tail 5
|
|
79
|
+
|
|
80
|
+
Verify clustered elastic-service on all nodes:
|
|
81
|
+
|
|
82
|
+
misterio --single-role elastic-service ps
|
|
83
|
+
|
|
84
|
+
Verify elastic service on just two nodes, named wonderboy and adam:
|
|
85
|
+
|
|
86
|
+
misterio -h wonderboy -h adam --single-role elastic-service ps
|
|
87
|
+
|
|
88
|
+
"""
|
|
89
|
+
if misterio_host is None or len(misterio_host) == 0:
|
|
90
|
+
misterio_host_list = os.listdir(os.path.join(home, "hosts"))
|
|
91
|
+
else:
|
|
92
|
+
misterio_host_list = misterio_host
|
|
93
|
+
print(f"MISTERIO HOME:{home} Host to be processed:{misterio_host_list}")
|
|
94
|
+
if list_flag:
|
|
95
|
+
for mhost in misterio_host_list:
|
|
96
|
+
try:
|
|
97
|
+
print(f"Roles for {mhost}")
|
|
98
|
+
for filename in os.listdir(os.path.join(home, "hosts", mhost)):
|
|
99
|
+
print(f"\t{filename}")
|
|
100
|
+
except FileNotFoundError:
|
|
101
|
+
print(f"No roles for {misterio_host}")
|
|
102
|
+
sys.exit(0)
|
|
103
|
+
for mhost in misterio_host_list:
|
|
104
|
+
docker_host = f"ssh://{mhost}"
|
|
105
|
+
os.environ["DOCKER_HOST"] = docker_host
|
|
106
|
+
print(f"=== {docker_host} ===")
|
|
107
|
+
hosts_path = os.path.join(home, "hosts", mhost)
|
|
108
|
+
for filename in os.listdir(hosts_path):
|
|
109
|
+
# print(filename)
|
|
110
|
+
if filename.endswith(".env"):
|
|
111
|
+
if single_role is None:
|
|
112
|
+
process_role(
|
|
113
|
+
home, os.path.join(hosts_path, filename), docker_command
|
|
114
|
+
)
|
|
115
|
+
else:
|
|
116
|
+
if single_role in filename:
|
|
117
|
+
process_role(
|
|
118
|
+
home, os.path.join(hosts_path, filename), docker_command
|
|
119
|
+
)
|