multivisor 6.0.1__tar.gz → 6.0.2__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.
- multivisor-6.0.2/PKG-INFO +375 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/README.md +11 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/multivisor.py +3 -3
- multivisor-6.0.2/multivisor/server/dist/static/js/app.52791f915c2f060b9cb1.js.map +1 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/dist/static/js/manifest.2ae2e69a05c33dfc65f8.js.map +1 -1
- multivisor-6.0.2/multivisor/server/dist/static/js/vendor.1d02877727062a41e9fb.js.map +1 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/web.py +2 -2
- multivisor-6.0.2/multivisor.egg-info/PKG-INFO +375 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor.egg-info/SOURCES.txt +1 -4
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor.egg-info/entry_points.txt +0 -1
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor.egg-info/top_level.txt +0 -1
- {multivisor-6.0.1 → multivisor-6.0.2}/setup.py +4 -4
- multivisor-6.0.1/PKG-INFO +0 -334
- multivisor-6.0.1/multivisor/server/dist/static/js/app.52791f915c2f060b9cb1.js.map +0 -1
- multivisor-6.0.1/multivisor/server/dist/static/js/vendor.1d02877727062a41e9fb.js.map +0 -1
- multivisor-6.0.1/multivisor.egg-info/PKG-INFO +0 -334
- multivisor-6.0.1/tests/__init__.py +0 -0
- multivisor-6.0.1/tests/conftest.py +0 -94
- multivisor-6.0.1/tests/functions.py +0 -3
- {multivisor-6.0.1 → multivisor-6.0.2}/LICENSE +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/__init__.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/client/__init__.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/client/cli.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/client/http.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/client/repl.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/client/util.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/rpc.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/__init__.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/dist/index.html +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/dist/static/css/app.2aff3580a128440bba89b94112292cb1.css +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/dist/static/css/app.2aff3580a128440bba89b94112292cb1.css.map +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/dist/static/js/app.52791f915c2f060b9cb1.js +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/dist/static/js/manifest.2ae2e69a05c33dfc65f8.js +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/dist/static/js/vendor.1d02877727062a41e9fb.js +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/rpc.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/tests/__init__.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/tests/conftest.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/tests/test_web.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/server/util.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/signals.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/tests/__init__.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/tests/test_multivisor.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor/util.py +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor.egg-info/dependency_links.txt +0 -0
- {multivisor-6.0.1 → multivisor-6.0.2}/multivisor.egg-info/requires.txt +11 -11
- {multivisor-6.0.1 → multivisor-6.0.2}/setup.cfg +0 -0
@@ -0,0 +1,375 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: multivisor
|
3
|
+
Version: 6.0.2
|
4
|
+
Summary: A centralized supervisor UI (web & CLI)
|
5
|
+
Author: Tiago Coutinho
|
6
|
+
Author-email: coutinhotiago@gmail.com
|
7
|
+
License: GNU General Public License v3
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
9
|
+
Classifier: Environment :: Console
|
10
|
+
Classifier: Environment :: Web Environment
|
11
|
+
Classifier: Framework :: Flask
|
12
|
+
Classifier: Intended Audience :: Developers
|
13
|
+
Classifier: Intended Audience :: Information Technology
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
15
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
16
|
+
Classifier: Natural Language :: English
|
17
|
+
Classifier: Operating System :: POSIX
|
18
|
+
Classifier: Operating System :: Microsoft :: Windows
|
19
|
+
Classifier: Programming Language :: Python
|
20
|
+
Classifier: Programming Language :: Python :: 2
|
21
|
+
Classifier: Programming Language :: Python :: 2.7
|
22
|
+
Classifier: Programming Language :: Python :: 3
|
23
|
+
Classifier: Programming Language :: Python :: 3.5
|
24
|
+
Classifier: Programming Language :: Python :: 3.6
|
25
|
+
Classifier: Programming Language :: Python :: 3.7
|
26
|
+
Classifier: Programming Language :: Python :: 3.8
|
27
|
+
Classifier: Programming Language :: Python :: 3.9
|
28
|
+
Classifier: Topic :: System :: Boot
|
29
|
+
Classifier: Topic :: System :: Monitoring
|
30
|
+
Classifier: Topic :: System :: Systems Administration
|
31
|
+
Description-Content-Type: text/markdown
|
32
|
+
License-File: LICENSE
|
33
|
+
Requires-Dist: six
|
34
|
+
Requires-Dist: gevent>=1.3
|
35
|
+
Provides-Extra: rpc
|
36
|
+
Requires-Dist: zerorpc; extra == "rpc"
|
37
|
+
Requires-Dist: supervisor; extra == "rpc"
|
38
|
+
Provides-Extra: web
|
39
|
+
Requires-Dist: flask; extra == "web"
|
40
|
+
Requires-Dist: werkzeug; extra == "web"
|
41
|
+
Requires-Dist: blinker; extra == "web"
|
42
|
+
Requires-Dist: zerorpc; extra == "web"
|
43
|
+
Requires-Dist: supervisor; extra == "web"
|
44
|
+
Provides-Extra: cli
|
45
|
+
Requires-Dist: maya; extra == "cli"
|
46
|
+
Requires-Dist: requests; extra == "cli"
|
47
|
+
Requires-Dist: prompt_toolkit>=2; extra == "cli"
|
48
|
+
Requires-Dist: blinker; extra == "cli"
|
49
|
+
Provides-Extra: all
|
50
|
+
Requires-Dist: blinker; extra == "all"
|
51
|
+
Requires-Dist: zerorpc; extra == "all"
|
52
|
+
Requires-Dist: werkzeug; extra == "all"
|
53
|
+
Requires-Dist: supervisor; extra == "all"
|
54
|
+
Requires-Dist: prompt_toolkit>=2; extra == "all"
|
55
|
+
Requires-Dist: maya; extra == "all"
|
56
|
+
Requires-Dist: flask; extra == "all"
|
57
|
+
Requires-Dist: requests; extra == "all"
|
58
|
+
Dynamic: author
|
59
|
+
Dynamic: author-email
|
60
|
+
Dynamic: classifier
|
61
|
+
Dynamic: description
|
62
|
+
Dynamic: description-content-type
|
63
|
+
Dynamic: license
|
64
|
+
Dynamic: license-file
|
65
|
+
Dynamic: provides-extra
|
66
|
+
Dynamic: requires-dist
|
67
|
+
Dynamic: summary
|
68
|
+
|
69
|
+
# Multivisor
|
70
|
+
|
71
|
+
<img width="60%" align="right" alt="multivisor web on chrome desktop app"
|
72
|
+
title="multivisor web on chrome desktop app"
|
73
|
+
src="doc/multivisor_desktop.png"
|
74
|
+
/>
|
75
|
+
|
76
|
+
|
77
|
+
[![Multivisor][pypi-version]](https://pypi.python.org/pypi/multivisor)
|
78
|
+
[![Python Versions][pypi-python-versions]](https://pypi.python.org/pypi/multivisor)
|
79
|
+
[![Pypi status][pypi-status]](https://pypi.python.org/pypi/multivisor)
|
80
|
+
![License][license]
|
81
|
+
[![Build Status][build]](https://travis-ci.org/guy881/multivisor)
|
82
|
+
|
83
|
+
A centralized supervisor UI (Web & CLI)
|
84
|
+
|
85
|
+
* Processes status always up to date
|
86
|
+
* Reactivity through asynchronous actions
|
87
|
+
* Notifications when state changes
|
88
|
+
* Mobile aware, SPA web page
|
89
|
+
* Powerful filters
|
90
|
+
* Interactive CLI
|
91
|
+
* works on [supervisor](https://pypi.org/project/supervisor/)
|
92
|
+
and [supervisor-win](https://pypi.org/project/supervisor-win/)
|
93
|
+
|
94
|
+
Multivisor is comprised of 3 components:
|
95
|
+
|
96
|
+
1. **web server**: gathers information from all supervisors and provides a
|
97
|
+
dashboard like UI to the entire system
|
98
|
+
1. **multivisor RPC**: an RPC extension to supervisor used to communicate
|
99
|
+
between each supervisord and multivisor web server
|
100
|
+
1. **CLI**: an optional CLI which communicates with multivisor web server
|
101
|
+
|
102
|
+
## Installation and configuration
|
103
|
+
|
104
|
+
The installation and configuration steps are exactly the same on Linux and
|
105
|
+
Windows.
|
106
|
+
|
107
|
+
Thanks to the [ESRF](https://esrf.eu) sponsorship, multivisor is able to work
|
108
|
+
well with [supervisor-win](https://pypi.org/project/supervisor-win/).
|
109
|
+
|
110
|
+
### RPC
|
111
|
+
|
112
|
+
The multivisor RPC must be installed in the same environment(s) as your
|
113
|
+
supervisord instances. It can be installed on python environments ranging from
|
114
|
+
2.7 to 3.x.
|
115
|
+
|
116
|
+
From within the same python environment as your supervisord process, type:
|
117
|
+
|
118
|
+
```bash
|
119
|
+
pip install multivisor[rpc]
|
120
|
+
```
|
121
|
+
|
122
|
+
There are two options to configure multivisor RPC: 1) as an extra
|
123
|
+
[rpcinterface](http://supervisord.org/configuration.html#rpcinterface-x-section-settings)
|
124
|
+
to supervisord or 2) an [eventlistener](http://supervisord.org/configuration.html#eventlistener-x-section-settings) process managed by supervisord.
|
125
|
+
|
126
|
+
The first option has the advantage of not requiring an extra process but it's
|
127
|
+
implementation relies on internal supervisord details. Therefore, the multivisor
|
128
|
+
author recommends using the 2nd approach.
|
129
|
+
|
130
|
+
#### Option 1: rpcinterface
|
131
|
+
|
132
|
+
Configure the multivisor rpc interface by adding the following lines
|
133
|
+
to your *supervisord.conf*:
|
134
|
+
|
135
|
+
```ini
|
136
|
+
[rpcinterface:multivisor]
|
137
|
+
supervisor.rpcinterface_factory = multivisor.rpc:make_rpc_interface
|
138
|
+
bind=*:9002
|
139
|
+
```
|
140
|
+
|
141
|
+
If no *bind* is given, it defaults to `*:9002`.
|
142
|
+
|
143
|
+
Repeat the above procedure for every supervisor you have running.
|
144
|
+
|
145
|
+
#### Option 2: eventlistener
|
146
|
+
|
147
|
+
Configure the multivisor rpc interface by adding the following lines
|
148
|
+
to your *supervisord.conf*:
|
149
|
+
|
150
|
+
```ini
|
151
|
+
[eventlistener:multivisor-rpc]
|
152
|
+
command=multivisor-rpc --bind 0:9002
|
153
|
+
events=PROCESS_STATE,SUPERVISOR_STATE_CHANGE
|
154
|
+
```
|
155
|
+
|
156
|
+
If no *bind* is given, it defaults to `*:9002`.
|
157
|
+
|
158
|
+
You are free to choose the event listener name. As a convention we propose
|
159
|
+
`multivisor-rpc`.
|
160
|
+
|
161
|
+
NB: Make sure that `multivisor-rpc` command is accessible or provide full PATH.
|
162
|
+
|
163
|
+
Repeat the above procedure for every supervisor you have running.
|
164
|
+
|
165
|
+
|
166
|
+
### Web server
|
167
|
+
|
168
|
+
The multivisor web server requires a python 3.x environment. It must be
|
169
|
+
installed on a machine with a network access to the different supervisors.
|
170
|
+
This is achieved with:
|
171
|
+
|
172
|
+
```bash
|
173
|
+
pip install multivisor[web]
|
174
|
+
```
|
175
|
+
|
176
|
+
The web server is configured with a INI like configuration file
|
177
|
+
(much like supervisor itself) that is passed as command line argument.
|
178
|
+
It is usually named *multivisor.conf* but can be any filename you which.
|
179
|
+
|
180
|
+
The file consists of a `global` section where you can give an optional name to
|
181
|
+
your multivisor instance (default is *multivisor*. This name will appear on the
|
182
|
+
top left corner of multivisor the web page).
|
183
|
+
|
184
|
+
To add a new supervisor to the list simply add a section `[supervisor:<name>]`.
|
185
|
+
It accepts an optional `url` in the format `[<host>][:<port>]`. The default
|
186
|
+
is `<name>:9002`.
|
187
|
+
|
188
|
+
Here is an example:
|
189
|
+
|
190
|
+
```ini
|
191
|
+
[global]
|
192
|
+
name=ACME
|
193
|
+
|
194
|
+
[supervisor:roadrunner]
|
195
|
+
# since no url is given it will be roadrunner:9002
|
196
|
+
|
197
|
+
[supervisor:coyote]
|
198
|
+
# no host is given: defaults to coyote
|
199
|
+
url=:9011
|
200
|
+
|
201
|
+
[supervisor:bugsbunny]
|
202
|
+
# no port is given: defaults to 9002
|
203
|
+
url=bugsbunny.acme.org
|
204
|
+
|
205
|
+
[supervisor:daffyduck]
|
206
|
+
url=daffyduck.acme.org:9007
|
207
|
+
```
|
208
|
+
|
209
|
+
<img width="40%" align="right" alt="multivisor web on mobile"
|
210
|
+
title="multivisor web on mobile"
|
211
|
+
src="doc/multivisor_mobile.png"
|
212
|
+
/>
|
213
|
+
|
214
|
+
Once installed and configured, the web server can be started from the command
|
215
|
+
line with:
|
216
|
+
|
217
|
+
```bash
|
218
|
+
multivisor -c ./multivisor.conf
|
219
|
+
```
|
220
|
+
|
221
|
+
Start a browser pointing to [localhost:22000](http://localhost:22000).
|
222
|
+
On a mobile device it should look something like the figure on the right.
|
223
|
+
|
224
|
+
Of course the multivisor web server itself can be configured in supervisor as a
|
225
|
+
normal program.
|
226
|
+
|
227
|
+
#### Authentication
|
228
|
+
|
229
|
+
To protect multivisor from unwanted access, you can enable authentication.
|
230
|
+
|
231
|
+
Specify `username` and `password` parameters in `global` section of your configuration file e.g.:
|
232
|
+
|
233
|
+
```ini
|
234
|
+
[global]
|
235
|
+
username=test
|
236
|
+
password=test
|
237
|
+
```
|
238
|
+
|
239
|
+
You can also specify `password` as SHA-1 hash in hex, with `{SHA}` prefix: e.g.
|
240
|
+
`{SHA}a94a8fe5ccb19ba61c4c0873d391e987982fbbd3` (example hash is `test` in SHA-1).
|
241
|
+
|
242
|
+
In order to use authentication, you also need to set `MULTIVISOR_SECRET_KEY` environmental variable,
|
243
|
+
as flask sessions module needs some secret value to create secure session.
|
244
|
+
You can generate some random hash easily using python:
|
245
|
+
`python -c 'import os; import binascii; print(binascii.hexlify(os.urandom(32)))'`
|
246
|
+
|
247
|
+
### CLI
|
248
|
+
|
249
|
+
The multivisor CLI is an optional component which can be installed with:
|
250
|
+
|
251
|
+
```bash
|
252
|
+
pip install multivisor[cli]
|
253
|
+
```
|
254
|
+
|
255
|
+
The CLI connects directly to the web server using an HTTP REST API.
|
256
|
+
It doesn't require any configuration.
|
257
|
+
|
258
|
+
It can be started with:
|
259
|
+
|
260
|
+
```bash
|
261
|
+
multivisor-cli --url localhost:22000
|
262
|
+
```
|
263
|
+
|
264
|
+

|
265
|
+
|
266
|
+
# Running the docker demo
|
267
|
+
|
268
|
+
```bash
|
269
|
+
$ docker-compose build --parallel
|
270
|
+
$ docker-compose up
|
271
|
+
```
|
272
|
+
|
273
|
+
That's it!
|
274
|
+
|
275
|
+
Start a browser pointing to [localhost:22000](http://localhost:22000).
|
276
|
+
|
277
|
+
# Running the example from scratch
|
278
|
+
|
279
|
+
```bash
|
280
|
+
# Fetch the project:
|
281
|
+
git clone https://github.com/tiagocoutinho/multivisor
|
282
|
+
cd multivisor
|
283
|
+
|
284
|
+
|
285
|
+
# Install frontend dependencies
|
286
|
+
npm install
|
287
|
+
# Build for production with minification
|
288
|
+
npm run build
|
289
|
+
|
290
|
+
# feel free to use your favorite python virtual environment
|
291
|
+
# here. Otherwise you will need administrative privileges
|
292
|
+
pip install .[all]
|
293
|
+
|
294
|
+
# Launch a few supervisors
|
295
|
+
mkdir examples/full_example/log
|
296
|
+
supervisord -c examples/full_example/supervisord_lid001.conf
|
297
|
+
supervisord -c examples/full_example/supervisord_lid002.conf
|
298
|
+
supervisord -c examples/full_example/supervisord_baslid001.conf
|
299
|
+
|
300
|
+
# Finally, launch multivisor:
|
301
|
+
multivisor -c examples/full_example/multivisor.conf
|
302
|
+
```
|
303
|
+
|
304
|
+
That's it!
|
305
|
+
|
306
|
+
Start a browser pointing to [localhost:22000](http://localhost:22000). On a mobile
|
307
|
+
device it should look something like this:
|
308
|
+
|
309
|
+

|
310
|
+
|
311
|
+
# Technologies
|
312
|
+
|
313
|
+

|
314
|
+
|
315
|
+
The `multivisor` backend runs a [flask](http://flask.pocoo.org/) web server.
|
316
|
+
|
317
|
+
The `multivisor-cli` runs a
|
318
|
+
[prompt-toolkit](http://python-prompt-toolkit.rtfd.io) based console.
|
319
|
+
|
320
|
+
The frontend is based on [vue](https://vuejs.org/) +
|
321
|
+
[vuex](https://vuex.vuejs.org/) + [vuetify](https://vuetifyjs.com/).
|
322
|
+
|
323
|
+
# Development
|
324
|
+
|
325
|
+
## Build & Install
|
326
|
+
|
327
|
+
```bash
|
328
|
+
|
329
|
+
# install frontend
|
330
|
+
npm install
|
331
|
+
|
332
|
+
# build for production with minification
|
333
|
+
npm run build
|
334
|
+
|
335
|
+
# install backend
|
336
|
+
pip install -e .
|
337
|
+
|
338
|
+
```
|
339
|
+
|
340
|
+
## Run
|
341
|
+
|
342
|
+
```bash
|
343
|
+
# serve at localhost:22000
|
344
|
+
multivisor -c multivisor.conf
|
345
|
+
```
|
346
|
+
|
347
|
+
Start a browser pointing to [localhost:22000](http://localhost:22000)
|
348
|
+
|
349
|
+
## Development mode
|
350
|
+
|
351
|
+
You can run the backend using the webpack dev server to facilitate your
|
352
|
+
development cycle:
|
353
|
+
|
354
|
+
First, start multivisor (which listens on 22000 by default):
|
355
|
+
|
356
|
+
```bash
|
357
|
+
python -m multivisor.server.web -c multivisor.conf
|
358
|
+
```
|
359
|
+
|
360
|
+
Now, in another console, run the webpack dev server (it will
|
361
|
+
transfer the requests between the browser and multivisor):
|
362
|
+
|
363
|
+
``` bash
|
364
|
+
npm run dev
|
365
|
+
```
|
366
|
+
|
367
|
+
That's it. If you modify `App.vue` for example, you should see the changes
|
368
|
+
directly on your browser.
|
369
|
+
|
370
|
+
|
371
|
+
[pypi-python-versions]: https://img.shields.io/pypi/pyversions/multivisor.svg
|
372
|
+
[pypi-version]: https://img.shields.io/pypi/v/multivisor.svg
|
373
|
+
[pypi-status]: https://img.shields.io/pypi/status/multivisor.svg
|
374
|
+
[license]: https://img.shields.io/pypi/l/multivisor.svg
|
375
|
+
[build]: https://travis-ci.org/guy881/multivisor.svg?branch=develop
|
@@ -195,6 +195,17 @@ multivisor-cli --url localhost:22000
|
|
195
195
|
|
196
196
|

|
197
197
|
|
198
|
+
# Running the docker demo
|
199
|
+
|
200
|
+
```bash
|
201
|
+
$ docker-compose build --parallel
|
202
|
+
$ docker-compose up
|
203
|
+
```
|
204
|
+
|
205
|
+
That's it!
|
206
|
+
|
207
|
+
Start a browser pointing to [localhost:22000](http://localhost:22000).
|
208
|
+
|
198
209
|
# Running the example from scratch
|
199
210
|
|
200
211
|
```bash
|
@@ -8,9 +8,9 @@ import weakref
|
|
8
8
|
from blinker import signal
|
9
9
|
|
10
10
|
try:
|
11
|
-
from ConfigParser import SafeConfigParser
|
11
|
+
from ConfigParser import SafeConfigParser as ConfigParser
|
12
12
|
except ImportError:
|
13
|
-
from configparser import
|
13
|
+
from configparser import ConfigParser
|
14
14
|
|
15
15
|
import zerorpc
|
16
16
|
from gevent import spawn, sleep, joinall
|
@@ -332,7 +332,7 @@ class Process(dict):
|
|
332
332
|
|
333
333
|
|
334
334
|
def load_config(config_file):
|
335
|
-
parser =
|
335
|
+
parser = ConfigParser()
|
336
336
|
parser.read(config_file)
|
337
337
|
dft_global = dict(name="multivisor")
|
338
338
|
|