├── docs
├── CHANGES.md
├── scenario_1.rst
├── scenario_2.rst
├── scenario_3.rst
├── images
│ ├── .directory
│ ├── star_button.png
│ ├── start_button.png
│ ├── stop_button.png
│ ├── crashed_running.png
│ ├── refresh_button.png
│ ├── restart_button.png
│ ├── shutdown_button.png
│ ├── supvisors_flask.png
│ ├── supvisors_menu.png
│ ├── standard_running.png
│ ├── autorefresh_button.png
│ ├── supvisors_gathering.png
│ ├── supvisors_main_page.png
│ ├── supvisors_scenario_1.png
│ ├── supvisors_scenario_2.png
│ ├── supvisors_scenario_3.png
│ ├── supvisors_flask_example.png
│ ├── supvisors_application_page.png
│ ├── supvisors_conciliation_page.png
│ ├── supvisors_address_host_section.png
│ ├── supvisors_main_page_user_sync.png
│ ├── supvisors_address_process_section.png
│ └── supvisors_conflict_application_page.png
├── requirements.txt
├── Makefile
├── index.rst
├── common.rst
├── conf.py
└── faq.rst
├── supvisors
├── client
│ ├── __init__.py
│ ├── java
│ │ ├── org
│ │ │ └── supvisors
│ │ │ │ └── common
│ │ │ │ ├── SupvisorsAnyInfo.java
│ │ │ │ ├── StartingFailureStrategy.java
│ │ │ │ ├── DistributionRule.java
│ │ │ │ ├── SupvisorsFailureStrategies.java
│ │ │ │ ├── ConciliationStrategy.java
│ │ │ │ ├── StartingStrategy.java
│ │ │ │ ├── RunningFailureStrategy.java
│ │ │ │ ├── LoggerLevels.java
│ │ │ │ ├── SupvisorsInstanceState.java
│ │ │ │ ├── SupvisorsState.java
│ │ │ │ ├── ProcessState.java
│ │ │ │ ├── SupervisorFaults.java
│ │ │ │ ├── SupervisorLogResult.java
│ │ │ │ ├── SupervisorState.java
│ │ │ │ ├── SupvisorsStateModes.java
│ │ │ │ ├── SupervisorConfigUpdates.java
│ │ │ │ └── SupvisorsStatus.java
│ │ └── build.xml
│ └── clientutils.py
├── tools
│ ├── __init__.py
│ ├── apis
│ │ ├── __init__.py
│ │ ├── system_namespace.py
│ │ └── utils.py
│ └── supvisorsflask.py
├── web
│ ├── __init__.py
│ └── viewmaintail.py
├── internal_com
│ └── __init__.py
├── version.txt
├── test
│ ├── scripts
│ │ ├── __init__.py
│ │ ├── java_client.sh
│ │ ├── stop_all.sh
│ │ ├── start_all.sh
│ │ ├── start_all_mc.sh
│ │ ├── evt_listener.py
│ │ ├── supervisorctl_test.sh
│ │ └── process_app.py
│ ├── etc
│ │ ├── supvisors01.cliche.bzh
│ │ ├── supvisors02.cliche.bzh
│ │ ├── common
│ │ │ ├── player
│ │ │ │ ├── group_player.ini
│ │ │ │ ├── program_movie_player.ini
│ │ │ │ └── program_test_reader.ini
│ │ │ ├── web_movies
│ │ │ │ ├── group_web_movies.ini
│ │ │ │ └── program_web_browser.ini
│ │ │ ├── database
│ │ │ │ ├── group_database.ini
│ │ │ │ ├── program_register_movies.ini
│ │ │ │ └── program_movie_server.ini
│ │ │ ├── import_database
│ │ │ │ ├── group_import_database.ini
│ │ │ │ ├── program_mount_disk.ini
│ │ │ │ └── program_copy_error.ini
│ │ │ └── my_movies
│ │ │ │ ├── group_my_movies.ini
│ │ │ │ ├── program_error_disk_writer.ini
│ │ │ │ ├── program_error_disk_reader.ini
│ │ │ │ ├── program_hmi.ini
│ │ │ │ ├── program_manager.ini
│ │ │ │ ├── program_web_server.ini
│ │ │ │ ├── program_converter.ini
│ │ │ │ ├── program_restart_application.ini
│ │ │ │ └── program_restart_process.ini
│ │ ├── rocky52
│ │ │ ├── group_service.ini
│ │ │ ├── program_disk_handler.ini
│ │ │ └── program_disk_writer.ini
│ │ ├── rocky51
│ │ │ ├── service
│ │ │ │ ├── group_service.ini
│ │ │ │ ├── program_flask.ini
│ │ │ │ ├── program_evt_listener.ini
│ │ │ │ ├── program_disk_reader.ini
│ │ │ │ └── program_disk_writer.ini
│ │ │ └── test
│ │ │ │ ├── group_test.ini
│ │ │ │ ├── program_check_flask.ini
│ │ │ │ ├── program_check_start_sequence.ini
│ │ │ │ ├── program_check_stop_sequence.ini
│ │ │ │ ├── program_check_running_strategy.ini
│ │ │ │ ├── program_check_starting_strategy.ini
│ │ │ │ └── program_check_conciliation_strategy.ini
│ │ ├── supv-03
│ │ │ └── program_disk_handler.ini
│ │ ├── my_movies_test.xml
│ │ ├── supervisord_alt_mc.conf
│ │ ├── supervisord_alt.conf
│ │ ├── supervisord_mc.conf
│ │ └── supervisord.conf
│ ├── use_cases
│ │ ├── gathering
│ │ │ ├── bin
│ │ │ │ ├── scen1
│ │ │ │ ├── scen2
│ │ │ │ └── scen3
│ │ │ ├── etc
│ │ │ │ ├── scenario_1
│ │ │ │ ├── scenario_2
│ │ │ │ ├── scenario_3
│ │ │ │ ├── supervisord_server_localhost.conf
│ │ │ │ ├── supervisord_server_mc.conf
│ │ │ │ ├── supervisord_console_mc.conf
│ │ │ │ ├── supervisord_console_localhost.conf
│ │ │ │ ├── supervisord_server.conf
│ │ │ │ └── supervisord_console.conf
│ │ │ ├── start_localhost_mc.sh
│ │ │ ├── start_localhost.sh
│ │ │ ├── start.sh
│ │ │ ├── start_mc.sh
│ │ │ └── configure.sh
│ │ ├── scenario_1
│ │ │ ├── etc
│ │ │ │ ├── supvisors01.cliche.bzh
│ │ │ │ ├── supvisors02.cliche.bzh
│ │ │ │ ├── supvisors03.cliche.bzh
│ │ │ │ ├── rocky52
│ │ │ │ │ ├── group_rocky52.ini
│ │ │ │ │ ├── wait_nfs_mount.ini
│ │ │ │ │ └── programs_rocky52.ini
│ │ │ │ ├── rocky53
│ │ │ │ │ ├── group_rocky53.ini
│ │ │ │ │ ├── wait_nfs_mount.ini
│ │ │ │ │ └── programs_rocky53.ini
│ │ │ │ ├── rocky51
│ │ │ │ │ ├── group_rocky51.ini
│ │ │ │ │ ├── wait_nfs_mount.ini
│ │ │ │ │ └── programs_rocky51.ini
│ │ │ │ ├── localhost
│ │ │ │ │ └── group_localhost.ini
│ │ │ │ ├── supervisord_localhost.conf
│ │ │ │ ├── supervisord_distributed.conf
│ │ │ │ ├── supervisord_distributed_mc.conf
│ │ │ │ └── supvisors_rules.xml
│ │ │ ├── bin
│ │ │ │ └── scen1
│ │ │ │ │ ├── wait_nfs_mount.sh
│ │ │ │ │ ├── common.sh
│ │ │ │ │ ├── hci.sh
│ │ │ │ │ ├── config_manager.sh
│ │ │ │ │ ├── data_processing.sh
│ │ │ │ │ ├── data_recorder.sh
│ │ │ │ │ ├── external_interface.sh
│ │ │ │ │ ├── sensor_acquisition.sh
│ │ │ │ │ └── sensor_processing.sh
│ │ │ ├── start_localhost.sh
│ │ │ ├── start.sh
│ │ │ └── start_mc.sh
│ │ ├── scenario_2
│ │ │ ├── bin
│ │ │ │ └── scen2
│ │ │ │ │ ├── check_internal_data_bus.sh
│ │ │ │ │ ├── common.sh
│ │ │ │ │ ├── chart_view.sh
│ │ │ │ │ ├── sensor_view.sh
│ │ │ │ │ ├── config_manager.sh
│ │ │ │ │ ├── data_processing.sh
│ │ │ │ │ ├── sensor_control.sh
│ │ │ │ │ ├── common_bus_interface.sh
│ │ │ │ │ ├── internal_data_bus.sh
│ │ │ │ │ ├── sensor_acquisition.sh
│ │ │ │ │ └── check_common_data_bus.sh
│ │ │ ├── etc
│ │ │ │ ├── console
│ │ │ │ │ ├── group_scen2_hci_01.ini
│ │ │ │ │ ├── group_scen2_hci_02.ini
│ │ │ │ │ ├── group_scen2_hci_03.ini
│ │ │ │ │ └── programs_console.ini
│ │ │ │ ├── server
│ │ │ │ │ ├── group_scen2_srv_01.ini
│ │ │ │ │ ├── group_scen2_srv_02.ini
│ │ │ │ │ ├── group_scen2_srv_03.ini
│ │ │ │ │ └── programs_server.ini
│ │ │ │ ├── common
│ │ │ │ │ └── programs_services.ini
│ │ │ │ ├── supervisord_server_mc.conf
│ │ │ │ ├── supervisord_console_mc.conf
│ │ │ │ ├── supervisord_server.conf
│ │ │ │ ├── supervisord_console.conf
│ │ │ │ ├── supvisors_rules_mc.xml
│ │ │ │ └── supvisors_rules.xml
│ │ │ ├── template_etc
│ │ │ │ ├── console
│ │ │ │ │ ├── group_console.ini
│ │ │ │ │ └── programs_console.ini
│ │ │ │ └── server
│ │ │ │ │ ├── group_server.ini
│ │ │ │ │ └── programs_server.ini
│ │ │ ├── start.sh
│ │ │ └── start_mc.sh
│ │ └── scenario_3
│ │ │ ├── bin
│ │ │ └── scen3
│ │ │ │ ├── common.sh
│ │ │ │ ├── chart_view.sh
│ │ │ │ ├── item_control.sh
│ │ │ │ ├── item_manager.sh
│ │ │ │ ├── system_health.sh
│ │ │ │ ├── track_manager.sh
│ │ │ │ ├── common_bus_interface.sh
│ │ │ │ ├── internal_data_bus.sh
│ │ │ │ ├── check_common_data_bus.sh
│ │ │ │ └── check_internal_data_bus.sh
│ │ │ ├── template_etc
│ │ │ └── console
│ │ │ │ ├── group_console.ini
│ │ │ │ └── programs_console.ini
│ │ │ ├── etc
│ │ │ ├── console
│ │ │ │ ├── console_1
│ │ │ │ │ └── group_scen3_hci_01.ini
│ │ │ │ ├── console_2
│ │ │ │ │ └── group_scen3_hci_02.ini
│ │ │ │ ├── console_3
│ │ │ │ │ └── group_scen3_hci_03.ini
│ │ │ │ ├── console_4
│ │ │ │ │ └── group_scen3_hci_04.ini
│ │ │ │ ├── console_5
│ │ │ │ │ └── group_scen3_hci_05.ini
│ │ │ │ └── programs_console.ini
│ │ │ ├── common
│ │ │ │ └── group_services.ini
│ │ │ ├── supervisord_server_mc.conf
│ │ │ ├── supervisord_server.conf
│ │ │ ├── supervisord_console.conf
│ │ │ ├── supervisord_console_mc.conf
│ │ │ ├── server
│ │ │ │ └── group_server.ini
│ │ │ ├── supvisors_rules_mc.xml
│ │ │ └── supvisors_rules.xml
│ │ │ ├── configure.sh
│ │ │ ├── start.sh
│ │ │ └── start_mc.sh
│ ├── test_supervisor_177
│ │ ├── bin
│ │ │ └── evt_listener.py
│ │ └── etc
│ │ │ └── supervisord.conf
│ └── ui
│ │ └── test.css
├── tests
│ ├── __init__.py
│ ├── test_clientutils.py
│ └── test_plot.py
├── ui
│ ├── img
│ │ ├── icon.png
│ │ ├── erro_20.png
│ │ ├── info_20.png
│ │ ├── stop_40.png
│ │ ├── warn_20.png
│ │ ├── reload_30.png
│ │ ├── restart_40.png
│ │ ├── start_40.png
│ │ ├── supvisors.png
│ │ ├── leds_red_30.png
│ │ ├── red_light_30.png
│ │ ├── shutdown_40.png
│ │ ├── arrow-orange_12.png
│ │ ├── auto_reload_30.png
│ │ ├── leds_empty_30.png
│ │ ├── leds_green_30.png
│ │ ├── leds_yellow_30.png
│ │ └── model
│ │ │ ├── supvisors_icon.xcf
│ │ │ └── supvisors_logo.xcf
│ ├── fonts
│ │ ├── Kingthings_Calligraphica_2-webfont.eot
│ │ ├── Kingthings_Calligraphica_2-webfont.ttf
│ │ └── Kingthings_Calligraphica_2-webfont.woff
│ └── css
│ │ ├── proc_instance.css
│ │ ├── instance.css
│ │ ├── conciliation.css
│ │ ├── card.css
│ │ ├── application.css
│ │ ├── index.css
│ │ ├── message.css
│ │ ├── button.css
│ │ ├── header.css
│ │ └── process_table.css
├── external_com
│ └── __init__.py
└── __init__.py
├── setup.cfg
├── MANIFEST.in
├── .coveragerc
├── .gitignore
├── .readthedocs.yaml
├── tox.ini
└── .github
└── workflows
└── ci.yml
/docs/CHANGES.md:
--------------------------------------------------------------------------------
1 | ../CHANGES.md
--------------------------------------------------------------------------------
/supvisors/client/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/supvisors/tools/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/supvisors/web/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/supvisors/internal_com/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/supvisors/version.txt:
--------------------------------------------------------------------------------
1 | version=0.19
2 |
--------------------------------------------------------------------------------
/supvisors/test/scripts/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/supvisors/test/etc/supvisors01.cliche.bzh:
--------------------------------------------------------------------------------
1 | rocky51
--------------------------------------------------------------------------------
/supvisors/test/etc/supvisors02.cliche.bzh:
--------------------------------------------------------------------------------
1 | rocky52
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | description_file = README.md
3 |
--------------------------------------------------------------------------------
/docs/scenario_1.rst:
--------------------------------------------------------------------------------
1 | ../supvisors/test/use_cases/scenario_1/scenario_1.rst
--------------------------------------------------------------------------------
/docs/scenario_2.rst:
--------------------------------------------------------------------------------
1 | ../supvisors/test/use_cases/scenario_2/scenario_2.rst
--------------------------------------------------------------------------------
/docs/scenario_3.rst:
--------------------------------------------------------------------------------
1 | ../supvisors/test/use_cases/scenario_3/scenario_3.rst
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/bin/scen1:
--------------------------------------------------------------------------------
1 | ../../scenario_1/bin/scen1
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/bin/scen2:
--------------------------------------------------------------------------------
1 | ../../scenario_2/bin/scen2
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/bin/scen3:
--------------------------------------------------------------------------------
1 | ../../scenario_3/bin/scen3
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/etc/scenario_1:
--------------------------------------------------------------------------------
1 | ../../scenario_1/etc
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/etc/scenario_2:
--------------------------------------------------------------------------------
1 | ../../scenario_2/etc
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/etc/scenario_3:
--------------------------------------------------------------------------------
1 | ../../scenario_3/etc
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/supvisors01.cliche.bzh:
--------------------------------------------------------------------------------
1 | rocky51
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/supvisors02.cliche.bzh:
--------------------------------------------------------------------------------
1 | rocky52
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/supvisors03.cliche.bzh:
--------------------------------------------------------------------------------
1 | rocky53
--------------------------------------------------------------------------------
/supvisors/test/test_supervisor_177/bin/evt_listener.py:
--------------------------------------------------------------------------------
1 | ../../scripts/evt_listener.py
--------------------------------------------------------------------------------
/supvisors/tests/__init__.py:
--------------------------------------------------------------------------------
1 | __import__('pkg_resources').declare_namespace(__name__)
2 |
--------------------------------------------------------------------------------
/supvisors/test/ui/test.css:
--------------------------------------------------------------------------------
1 | footer p:last-of-type {
2 | color: var(--crash-color);
3 | }
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/bin/scen1/wait_nfs_mount.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | sleep 5
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/bin/scen1/common.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | zenity --info --text=$1
3 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/bin/scen2/check_internal_data_bus.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | sleep 5
3 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/bin/scen2/common.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | zenity --info --text=$1
3 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/bin/scen3/common.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | zenity --info --text=$1
3 |
--------------------------------------------------------------------------------
/docs/images/.directory:
--------------------------------------------------------------------------------
1 | [Dolphin]
2 | PreviewsShown=true
3 | Timestamp=2017,8,10,18,24,35
4 | Version=3
5 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/player/group_player.ini:
--------------------------------------------------------------------------------
1 | [group:player]
2 | programs=test_reader,movie_player
3 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/web_movies/group_web_movies.ini:
--------------------------------------------------------------------------------
1 | [group:web_movies]
2 | programs=web_browser
3 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky52/group_service.ini:
--------------------------------------------------------------------------------
1 | [group:service]
2 | programs=disk_handler,disk_writer_82
3 |
--------------------------------------------------------------------------------
/supvisors/ui/img/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/icon.png
--------------------------------------------------------------------------------
/docs/images/star_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/star_button.png
--------------------------------------------------------------------------------
/docs/images/start_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/start_button.png
--------------------------------------------------------------------------------
/docs/images/stop_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/stop_button.png
--------------------------------------------------------------------------------
/supvisors/ui/img/erro_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/erro_20.png
--------------------------------------------------------------------------------
/supvisors/ui/img/info_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/info_20.png
--------------------------------------------------------------------------------
/supvisors/ui/img/stop_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/stop_40.png
--------------------------------------------------------------------------------
/supvisors/ui/img/warn_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/warn_20.png
--------------------------------------------------------------------------------
/docs/images/crashed_running.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/crashed_running.png
--------------------------------------------------------------------------------
/docs/images/refresh_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/refresh_button.png
--------------------------------------------------------------------------------
/docs/images/restart_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/restart_button.png
--------------------------------------------------------------------------------
/docs/images/shutdown_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/shutdown_button.png
--------------------------------------------------------------------------------
/docs/images/supvisors_flask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_flask.png
--------------------------------------------------------------------------------
/docs/images/supvisors_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_menu.png
--------------------------------------------------------------------------------
/supvisors/test/etc/common/database/group_database.ini:
--------------------------------------------------------------------------------
1 | [group:database]
2 | programs=movie_server,register_movies
3 |
--------------------------------------------------------------------------------
/supvisors/ui/img/reload_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/reload_30.png
--------------------------------------------------------------------------------
/supvisors/ui/img/restart_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/restart_40.png
--------------------------------------------------------------------------------
/supvisors/ui/img/start_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/start_40.png
--------------------------------------------------------------------------------
/supvisors/ui/img/supvisors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/supvisors.png
--------------------------------------------------------------------------------
/docs/images/standard_running.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/standard_running.png
--------------------------------------------------------------------------------
/supvisors/ui/img/leds_red_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/leds_red_30.png
--------------------------------------------------------------------------------
/supvisors/ui/img/red_light_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/red_light_30.png
--------------------------------------------------------------------------------
/supvisors/ui/img/shutdown_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/shutdown_40.png
--------------------------------------------------------------------------------
/docs/images/autorefresh_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/autorefresh_button.png
--------------------------------------------------------------------------------
/docs/images/supvisors_gathering.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_gathering.png
--------------------------------------------------------------------------------
/docs/images/supvisors_main_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_main_page.png
--------------------------------------------------------------------------------
/docs/images/supvisors_scenario_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_scenario_1.png
--------------------------------------------------------------------------------
/docs/images/supvisors_scenario_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_scenario_2.png
--------------------------------------------------------------------------------
/docs/images/supvisors_scenario_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_scenario_3.png
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/service/group_service.ini:
--------------------------------------------------------------------------------
1 | [group:service]
2 | programs=disk_handler,disk_writer_81,supvisorsflask
3 |
--------------------------------------------------------------------------------
/supvisors/ui/img/arrow-orange_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/arrow-orange_12.png
--------------------------------------------------------------------------------
/supvisors/ui/img/auto_reload_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/auto_reload_30.png
--------------------------------------------------------------------------------
/supvisors/ui/img/leds_empty_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/leds_empty_30.png
--------------------------------------------------------------------------------
/supvisors/ui/img/leds_green_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/leds_green_30.png
--------------------------------------------------------------------------------
/supvisors/ui/img/leds_yellow_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/leds_yellow_30.png
--------------------------------------------------------------------------------
/supvisors/test/etc/common/import_database/group_import_database.ini:
--------------------------------------------------------------------------------
1 | [group:import_database]
2 | programs=mount_disk,copy_error
3 |
--------------------------------------------------------------------------------
/docs/images/supvisors_flask_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_flask_example.png
--------------------------------------------------------------------------------
/supvisors/ui/img/model/supvisors_icon.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/model/supvisors_icon.xcf
--------------------------------------------------------------------------------
/supvisors/ui/img/model/supvisors_logo.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/img/model/supvisors_logo.xcf
--------------------------------------------------------------------------------
/docs/images/supvisors_application_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_application_page.png
--------------------------------------------------------------------------------
/docs/images/supvisors_conciliation_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_conciliation_page.png
--------------------------------------------------------------------------------
/docs/images/supvisors_address_host_section.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_address_host_section.png
--------------------------------------------------------------------------------
/docs/images/supvisors_main_page_user_sync.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_main_page_user_sync.png
--------------------------------------------------------------------------------
/docs/images/supvisors_address_process_section.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_address_process_section.png
--------------------------------------------------------------------------------
/docs/images/supvisors_conflict_application_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/docs/images/supvisors_conflict_application_page.png
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | sphinx==7.2.6
2 | renku-sphinx-theme==0.4.0
3 | myst-parser==2.0.0
4 | supervisor==4.2.5
5 | websockets==11.0.3
6 | pyzmq==25.1.1
7 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/rocky52/group_rocky52.ini:
--------------------------------------------------------------------------------
1 | [group:scen1]
2 | programs=scen1_wait_nfs_mount_2,scen1_sensor_acquisition_1,scen1_sensor_processing_1
3 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/rocky53/group_rocky53.ini:
--------------------------------------------------------------------------------
1 | [group:scen1]
2 | programs=scen1_wait_nfs_mount_3,scen1_sensor_acquisition_2,scen1_sensor_processing_2
3 |
--------------------------------------------------------------------------------
/supvisors/ui/fonts/Kingthings_Calligraphica_2-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/fonts/Kingthings_Calligraphica_2-webfont.eot
--------------------------------------------------------------------------------
/supvisors/ui/fonts/Kingthings_Calligraphica_2-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/fonts/Kingthings_Calligraphica_2-webfont.ttf
--------------------------------------------------------------------------------
/supvisors/ui/fonts/Kingthings_Calligraphica_2-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julien6387/supvisors/HEAD/supvisors/ui/fonts/Kingthings_Calligraphica_2-webfont.woff
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/bin/scen1/hci.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/template_etc/console/group_console.ini:
--------------------------------------------------------------------------------
1 | [group:scen3_hci]
2 | programs=scen3_chart_view,scen3_item_control,scen3_check_internal_data_bus
3 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/bin/scen2/chart_view.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/bin/scen2/sensor_view.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/bin/scen3/chart_view.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/bin/scen1/config_manager.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/bin/scen1/data_processing.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/bin/scen1/data_recorder.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/bin/scen2/config_manager.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/bin/scen2/data_processing.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/bin/scen2/sensor_control.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/bin/scen3/item_control.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/bin/scen3/item_manager.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/bin/scen3/system_health.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/bin/scen3/track_manager.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/bin/scen1/external_interface.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/bin/scen1/sensor_acquisition.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/bin/scen1/sensor_processing.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/bin/scen2/common_bus_interface.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/bin/scen2/internal_data_bus.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/bin/scen2/sensor_acquisition.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/bin/scen3/common_bus_interface.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/bin/scen3/internal_data_bus.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | test_dir=$(dirname "$(readlink -f "$0")")
4 |
5 | $test_dir/common.sh ${SUPERVISOR_PROCESS_NAME}
6 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/console/console_1/group_scen3_hci_01.ini:
--------------------------------------------------------------------------------
1 | [group:scen3_hci_01]
2 | programs = scen3_chart_view,scen3_item_control,scen3_check_internal_data_bus
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/console/console_2/group_scen3_hci_02.ini:
--------------------------------------------------------------------------------
1 | [group:scen3_hci_02]
2 | programs = scen3_chart_view,scen3_item_control,scen3_check_internal_data_bus
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/console/console_3/group_scen3_hci_03.ini:
--------------------------------------------------------------------------------
1 | [group:scen3_hci_03]
2 | programs = scen3_chart_view,scen3_item_control,scen3_check_internal_data_bus
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/console/console_4/group_scen3_hci_04.ini:
--------------------------------------------------------------------------------
1 | [group:scen3_hci_04]
2 | programs = scen3_chart_view,scen3_item_control,scen3_check_internal_data_bus
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/console/console_5/group_scen3_hci_05.ini:
--------------------------------------------------------------------------------
1 | [group:scen3_hci_05]
2 | programs = scen3_chart_view,scen3_item_control,scen3_check_internal_data_bus
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/my_movies/group_my_movies.ini:
--------------------------------------------------------------------------------
1 | [group:my_movies]
2 | programs=manager,web_server,hmi,error_disk_reader,error_disk_writer,converter,restart_process,restart_application
3 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include CHANGES.md
2 | include LICENSE
3 | include supvisors/version.txt
4 | include supvisors/rules.xsd
5 | graft supvisors/doc
6 | graft supvisors/ui
7 | prune supvisors/ui/img/model
8 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/test/group_test.ini:
--------------------------------------------------------------------------------
1 | [group:test]
2 | programs=check_start_sequence,check_stop_sequence,check_conciliation_strategy,check_starting_strategy,check_running_strategy,check_flask
3 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/rocky51/group_rocky51.ini:
--------------------------------------------------------------------------------
1 | [group:scen1]
2 | programs=scen1_wait_nfs_mount_1,scen1_hci,scen1_config_manager,scen1_data_processing,scen1_external_interface,scen1_data_recorder
3 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/console/group_scen2_hci_01.ini:
--------------------------------------------------------------------------------
1 | [group:scen2_hci_01]
2 | programs = scen2_chart_view,scen2_sensor_control,scen2_sensor_view,scen2_check_internal_data_bus,scen2_internal_data_bus
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/console/group_scen2_hci_02.ini:
--------------------------------------------------------------------------------
1 | [group:scen2_hci_02]
2 | programs = scen2_chart_view,scen2_sensor_control,scen2_sensor_view,scen2_check_internal_data_bus,scen2_internal_data_bus
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/console/group_scen2_hci_03.ini:
--------------------------------------------------------------------------------
1 | [group:scen2_hci_03]
2 | programs = scen2_chart_view,scen2_sensor_control,scen2_sensor_view,scen2_check_internal_data_bus,scen2_internal_data_bus
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/template_etc/console/group_console.ini:
--------------------------------------------------------------------------------
1 | [group:scen2_hci]
2 | programs=scen2_chart_view,scen2_sensor_control,scen2_sensor_view,scen2_check_internal_data_bus,scen2_internal_data_bus
3 |
4 |
--------------------------------------------------------------------------------
/.coveragerc:
--------------------------------------------------------------------------------
1 | [run]
2 | omit =
3 | supvisors/__init__.py
4 | supvisors/tests/__init__.py
5 | supvisors/tools/__init__.py
6 |
7 | [report]
8 | exclude_also =
9 | if __name__ == .__main__.:
10 | def test_.*_deprecated.*:
11 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/server/group_scen2_srv_01.ini:
--------------------------------------------------------------------------------
1 | [group:scen2_srv_01]
2 | programs = scen2_config_manager,scen2_common_bus_interface,scen2_check_common_data_bus,scen2_check_internal_data_bus,scen2_internal_data_bus,scen2_data_processing,scen2_sensor_acquisition
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/server/group_scen2_srv_02.ini:
--------------------------------------------------------------------------------
1 | [group:scen2_srv_02]
2 | programs = scen2_config_manager,scen2_common_bus_interface,scen2_check_common_data_bus,scen2_check_internal_data_bus,scen2_internal_data_bus,scen2_data_processing,scen2_sensor_acquisition
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/server/group_scen2_srv_03.ini:
--------------------------------------------------------------------------------
1 | [group:scen2_srv_03]
2 | programs = scen2_config_manager,scen2_common_bus_interface,scen2_check_common_data_bus,scen2_check_internal_data_bus,scen2_internal_data_bus,scen2_data_processing,scen2_sensor_acquisition
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/template_etc/server/group_server.ini:
--------------------------------------------------------------------------------
1 | [group:scen2_srv]
2 | programs=scen2_config_manager,scen2_common_bus_interface,scen2_check_common_data_bus,scen2_check_internal_data_bus,scen2_internal_data_bus,scen2_data_processing,scen2_sensor_acquisition
3 |
4 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/localhost/group_localhost.ini:
--------------------------------------------------------------------------------
1 | [group:scen1]
2 | programs=scen1_hci,scen1_config_manager,scen1_data_processing,scen1_external_interface,scen1_data_recorder,scen1_sensor_acquisition_1,scen1_sensor_processing_1,scen1_sensor_acquisition_2,scen1_sensor_processing_2
3 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/rocky51/wait_nfs_mount.ini:
--------------------------------------------------------------------------------
1 | [program:scen1_wait_nfs_mount_1]
2 | command=bin/scen1/wait_nfs_mount.sh
3 | autostart=false
4 | killasgroup=true
5 | stopasgroup=true
6 | redirect_stderr=true
7 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
8 | stdout_logfile_backups=5
9 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/rocky52/wait_nfs_mount.ini:
--------------------------------------------------------------------------------
1 | [program:scen1_wait_nfs_mount_2]
2 | command=bin/scen1/wait_nfs_mount.sh
3 | autostart=false
4 | killasgroup=true
5 | stopasgroup=true
6 | redirect_stderr=true
7 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
8 | stdout_logfile_backups=5
9 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/rocky53/wait_nfs_mount.ini:
--------------------------------------------------------------------------------
1 | [program:scen1_wait_nfs_mount_3]
2 | command=bin/scen1/wait_nfs_mount.sh
3 | autostart=false
4 | killasgroup=true
5 | stopasgroup=true
6 | redirect_stderr=true
7 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
8 | stdout_logfile_backups=5
9 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/common/programs_services.ini:
--------------------------------------------------------------------------------
1 | [program:common_data_bus]
2 | command = zenity --info --text=%(program_name)s
3 | startsecs = 40
4 | killasgroup = true
5 | stopasgroup = true
6 | redirect_stderr = true
7 | stdout_logfile = log/%(program_name)s_%(host_node_name)s.log
8 | stdout_logfile_backups = 5
9 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/my_movies/program_error_disk_writer.ini:
--------------------------------------------------------------------------------
1 | [program:error_disk_writer]
2 | command=python ./scripts/process_app.py -n %(program_name)s -x 2
3 | autostart=false
4 | autorestart=false
5 | startsecs=5
6 | startretries=1
7 | exitcodes=1
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | stdout_logfile=NONE
11 | stderr_logfile=OFF
12 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/player/program_movie_player.ini:
--------------------------------------------------------------------------------
1 | [program:movie_player]
2 | command=python ./scripts/process_app.py -n %(program_name)s
3 | autostart=false
4 | autorestart=false
5 | startretries=0
6 | redirect_stderr=true
7 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
8 | stdout_logfile_maxbytes=1MB
9 | stdout_logfile_backups=1
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .directory/
2 | *.pyc
3 | *.pyo
4 | *.orig
5 | *.bak
6 | *.rej
7 | *.class
8 | *.jar
9 | *~
10 | build/
11 | .build/
12 | .eggs/
13 | .idea/
14 | .settings/
15 | dist/
16 | cur/
17 | htmlcov/
18 | log/
19 | tmp/
20 | venv/
21 | __pycache__/
22 | *.DS_Store
23 | *.log
24 | *.coverage
25 | *.egg-info
26 | .project
27 | coverage.xml
28 | nosetests.xml
29 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/service/program_flask.ini:
--------------------------------------------------------------------------------
1 | [program:supvisorsflask]
2 | command=supvisorsflask -u http://supv01:30000
3 | autostart=true
4 | autorestart=unexpected
5 | startsecs=2
6 | startretries=0
7 | redirect_stderr=true
8 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s_out.log
9 | stdout_logfile_maxbytes=10KB
10 | stdout_logfile_backups=1
11 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/web_movies/program_web_browser.ini:
--------------------------------------------------------------------------------
1 | [program:web_browser]
2 | command=firefox --new-instance http://localhost:60000
3 | autostart=false
4 | autorestart=unexpected
5 | startsecs=5
6 | startretries=0
7 | redirect_stderr=true
8 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
9 | stdout_logfile_maxbytes=1MB
10 | stdout_logfile_backups=1
11 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/my_movies/program_error_disk_reader.ini:
--------------------------------------------------------------------------------
1 | [program:error_disk_reader]
2 | command=python ./scripts/process_app.py -n %(program_name)s -x 10 ; exit 11
3 | autostart=false
4 | autorestart=false
5 | startsecs=2
6 | startretries=3
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | redirect_stderr=True
11 | stdout_logfile=NONE
12 | stderr_logfile=OFF
13 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/service/program_evt_listener.ini:
--------------------------------------------------------------------------------
1 | [eventlistener:evt_listener]
2 | command=python ./scripts/evt_listener.py
3 | process_name=evt_listener_%(process_num)02d
4 | events=EVENT
5 | buffer_size=50
6 | autostart=true
7 | autorestart=false
8 | startsecs=1
9 | startretries=0
10 | stderr_logfile=./log/%(program_name)s_%(process_num)02d_%(host_node_name)s_err.log
11 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/test/program_check_flask.ini:
--------------------------------------------------------------------------------
1 | [program:check_flask]
2 | command=./scripts/supvisorsflask_test.sh
3 | autostart=false
4 | autorestart=false
5 | startsecs=0
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | redirect_stderr=true
11 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
12 | stdout_logfile_maxbytes=1MB
13 | stdout_logfile_backups=1
14 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/import_database/program_mount_disk.ini:
--------------------------------------------------------------------------------
1 | [program:mount_disk]
2 | command=python ./scripts/process_app.py -n %(program_name)s
3 | process_name=mount_disk_%(process_num)02d
4 | numprocs=2
5 | autostart=false
6 | autorestart=false
7 | startsecs=0
8 | redirect_stderr=true
9 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
10 | stdout_logfile_maxbytes=1MB
11 | stdout_logfile_backups=1
12 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/my_movies/program_hmi.ini:
--------------------------------------------------------------------------------
1 | [program:hmi]
2 | command=python ./scripts/process_app.py -n %(program_name)s
3 | autostart=false
4 | autorestart=unexpected
5 | startsecs=2
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | stdout_logfile=None
11 | stderr_logfile=./log/%(program_name)s_%(host_node_name)s_err.log
12 | stderr_logfile_maxbytes=10KB
13 | stderr_logfile_backups=1
14 |
--------------------------------------------------------------------------------
/supvisors/test/scripts/java_client.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | ANT_FILE=../client/java/build.xml
4 |
5 | # test JAVA supvisors events
6 | ant -f $ANT_FILE run_supvisors_evt
7 |
8 | # test JAVA system XML-RPC
9 | ant -f $ANT_FILE run_system_rpc
10 |
11 | # test JAVA supervisor XML-RPC
12 | ant -f $ANT_FILE run_supervisor_rpc
13 |
14 | sleep 100
15 |
16 | # test JAVA supvisors XML-RPC
17 | ant -f $ANT_FILE run_supvisors_rpc
18 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/my_movies/program_manager.ini:
--------------------------------------------------------------------------------
1 | [program:manager]
2 | command=python ./scripts/process_app.py -n %(program_name)s
3 | autostart=false
4 | autorestart=unexpected
5 | startsecs=0
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s_out.log
11 | stdout_logfile_maxbytes=10KB
12 | stdout_logfile_backups=1
13 | stderr_logfile=off
14 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/player/program_test_reader.ini:
--------------------------------------------------------------------------------
1 | ; test a process that exits with an unexpected exit code
2 | [program:test_reader]
3 | command=python ./scripts/process_app.py -n %(program_name)s -x 2
4 | autostart=false
5 | autorestart=false
6 | startretries=0
7 | exitcodes=5
8 | redirect_stderr=true
9 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
10 | stdout_logfile_maxbytes=1MB
11 | stdout_logfile_backups=1
12 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/test/program_check_start_sequence.ini:
--------------------------------------------------------------------------------
1 | [program:check_start_sequence]
2 | command=python -m unittest scripts.check_start_sequence
3 | autostart=false
4 | autorestart=false
5 | startsecs=40
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | redirect_stderr=true
11 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
12 | stdout_logfile_maxbytes=1MB
13 | stdout_logfile_backups=1
14 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/test/program_check_stop_sequence.ini:
--------------------------------------------------------------------------------
1 | [program:check_stop_sequence]
2 | command=python -m unittest -c scripts.check_stop_sequence
3 | autostart=false
4 | autorestart=false
5 | startsecs=0
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=INT
9 | stopwaitsecs=10
10 | redirect_stderr=true
11 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
12 | stdout_logfile_maxbytes=1MB
13 | stdout_logfile_backups=1
14 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/test/program_check_running_strategy.ini:
--------------------------------------------------------------------------------
1 | [program:check_running_strategy]
2 | command=python -m unittest scripts.check_running_strategy
3 | autostart=false
4 | autorestart=false
5 | startsecs=0
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | redirect_stderr=true
11 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
12 | stdout_logfile_maxbytes=1MB
13 | stdout_logfile_backups=1
14 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/bin/scen2/check_common_data_bus.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function common_data_bus_running() {
4 | local result=`supervisorctl -s http://localhost:61000 status common_data_bus | awk '{print $2}'`
5 | echo $result
6 | }
7 |
8 | while [ $(common_data_bus_running) != "RUNNING" ]
9 | do
10 | echo "Waiting for common_data_bus to be RUNNING"
11 | sleep 1
12 | done
13 |
14 | echo "common_data_bus is RUNNING"
15 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/bin/scen3/check_common_data_bus.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function common_data_bus_running() {
4 | local result=`supervisorctl -s http://localhost:61000 status common_data_bus | awk '{print $2}'`
5 | echo $result
6 | }
7 |
8 | while [ $(common_data_bus_running) != "RUNNING" ]
9 | do
10 | echo "Waiting for common_data_bus to be RUNNING"
11 | sleep 1
12 | done
13 |
14 | echo "common_data_bus is RUNNING"
15 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/import_database/program_copy_error.ini:
--------------------------------------------------------------------------------
1 | ; test a process that exits before its RUNNING state is reached
2 | [program:copy_error]
3 | command=python ./scripts/process_app.py -n %(program_name)s -x 10
4 | autostart=false
5 | autorestart=false
6 | startsecs=15
7 | startretries=0
8 | redirect_stderr=true
9 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
10 | stdout_logfile_maxbytes=1MB
11 | stdout_logfile_backups=1
12 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/test/program_check_starting_strategy.ini:
--------------------------------------------------------------------------------
1 | [program:check_starting_strategy]
2 | command=python -m unittest scripts.check_starting_strategy
3 | autostart=false
4 | autorestart=false
5 | startsecs=0
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | redirect_stderr=true
11 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
12 | stdout_logfile_maxbytes=1MB
13 | stdout_logfile_backups=1
14 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/my_movies/program_web_server.ini:
--------------------------------------------------------------------------------
1 | [program:web_server]
2 | command=python ./scripts/process_app.py -n %(program_name)s
3 | autostart=false
4 | startsecs=5
5 | startretries=0
6 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s_out.log
7 | stdout_logfile_maxbytes=10KB
8 | stdout_logfile_backups=1
9 | stderr_logfile=./log/%(program_name)s_%(host_node_name)s_err.log
10 | stderr_logfile_maxbytes=10KB
11 | stderr_logfile_backups=1
12 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/test/program_check_conciliation_strategy.ini:
--------------------------------------------------------------------------------
1 | [program:check_conciliation_strategy]
2 | command=python -m unittest scripts.check_conciliation_strategy
3 | autostart=false
4 | autorestart=false
5 | startsecs=0
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | redirect_stderr=true
11 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
12 | stdout_logfile_maxbytes=1MB
13 | stdout_logfile_backups=1
14 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky52/program_disk_handler.ini:
--------------------------------------------------------------------------------
1 | [program:disk_handler]
2 | command=python ./scripts/process_app.py -n %(program_name)s
3 | autostart=true
4 | autorestart=false
5 | startsecs=2
6 | startretries=0
7 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s_out.log
8 | stdout_logfile_maxbytes=10KB
9 | stdout_logfile_backups=1
10 | stderr_logfile=./log/%(program_name)s_%(host_node_name)s_err.log
11 | stderr_logfile_maxbytes=10KB
12 | stderr_logfile_backups=1
13 |
--------------------------------------------------------------------------------
/supvisors/test/etc/supv-03/program_disk_handler.ini:
--------------------------------------------------------------------------------
1 | [program:disk_handler]
2 | command=python ./scripts/process_app.py -n %(program_name)s
3 | autostart=true
4 | autorestart=false
5 | startsecs=2
6 | startretries=0
7 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s_out.log
8 | stdout_logfile_maxbytes=10KB
9 | stdout_logfile_backups=1
10 | stderr_logfile=./log/%(program_name)s_%(host_node_name)s_err.log
11 | stderr_logfile_maxbytes=10KB
12 | stderr_logfile_backups=1
13 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/service/program_disk_reader.ini:
--------------------------------------------------------------------------------
1 | [program:disk_handler]
2 | command=python ./scripts/process_app.py -n %(program_name)s
3 | autostart=true
4 | autorestart=false
5 | startsecs=2
6 | startretries=0
7 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s_out.log
8 | stdout_logfile_maxbytes=10KB
9 | stdout_logfile_backups=1
10 | stderr_logfile=./log/%(program_name)s_%(host_node_name)s_err.log
11 | stderr_logfile_maxbytes=10KB
12 | stderr_logfile_backups=1
13 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/bin/scen3/check_internal_data_bus.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function internal_data_bus_running() {
4 | local result=`supvisorsctl -s ${SUPERVISOR_SERVER_URL} sstatus scen3_internal_data_bus | tail -1 | awk '{print $3}'`
5 | echo $result
6 | }
7 |
8 | while [ $(internal_data_bus_running) != "RUNNING" ]
9 | do
10 | echo "Waiting for scen3_internal_data_bus to be RUNNING"
11 | sleep 1
12 | done
13 |
14 | echo "scen3_internal_data_bus is RUNNING"
15 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/my_movies/program_converter.ini:
--------------------------------------------------------------------------------
1 | [program:converter]
2 | command=python ./scripts/process_app.py -n %(program_name)s -x 60
3 | process_name=converter_%(process_num)02d
4 | numprocs=15
5 | autostart=false
6 | autorestart=false
7 | startsecs=2
8 | startretries=0
9 | exitcodes=0
10 | stopsignal=TERM
11 | stopwaitsecs=10
12 | redirect_stderr=true
13 | stdout_logfile=./log/%(program_name)s_%(process_num)02d_%(host_node_name)s_out.log
14 | stdout_logfile_maxbytes=10KB
15 | stdout_logfile_backups=1
16 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/database/program_register_movies.ini:
--------------------------------------------------------------------------------
1 | [program:register_movies]
2 | command=python ./scripts/process_app.py -n %(program_name)s -x 5
3 | process_name=register_movies_%(process_num)02d
4 | numprocs=3
5 | numprocs_start=1
6 | autostart=false
7 | autorestart=false
8 | startsecs=1
9 | startretries=0
10 | exitcodes=0
11 | stopsignal=TERM
12 | stopwaitsecs=10
13 | redirect_stderr=true
14 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s.log
15 | stdout_logfile_maxbytes=1MB
16 | stdout_logfile_backups=1
17 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky52/program_disk_writer.ini:
--------------------------------------------------------------------------------
1 | [program:disk_writer_82]
2 | command=python ./scripts/process_app.py -n %(program_name)s -x 30
3 | autostart=false
4 | autorestart=false
5 | startsecs=5
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s_out.log
11 | stdout_logfile_maxbytes=10KB
12 | stdout_logfile_backups=1
13 | stderr_logfile=./log/%(program_name)s_%(host_node_name)s_err.log
14 | stderr_logfile_maxbytes=10KB
15 | stderr_logfile_backups=1
16 |
--------------------------------------------------------------------------------
/supvisors/test/etc/rocky51/service/program_disk_writer.ini:
--------------------------------------------------------------------------------
1 | [program:disk_writer_81]
2 | command=python ./scripts/process_app.py -n %(program_name)s -x 30
3 | autostart=false
4 | autorestart=false
5 | startsecs=5
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s_out.log
11 | stdout_logfile_maxbytes=10KB
12 | stdout_logfile_backups=1
13 | stderr_logfile=./log/%(program_name)s_%(host_node_name)s_err.log
14 | stderr_logfile_maxbytes=10KB
15 | stderr_logfile_backups=1
16 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/database/program_movie_server.ini:
--------------------------------------------------------------------------------
1 | [program:movie_server]
2 | command=python ./scripts/process_app.py -n %(program_name)s_%(process_num)02d
3 | process_name=movie_server_%(process_num)02d
4 | numprocs=3
5 | numprocs_start=1
6 | autostart=false
7 | autorestart=false
8 | startsecs=1
9 | startretries=0
10 | exitcodes=0
11 | stopsignal=TERM
12 | stopwaitsecs=10
13 | redirect_stderr=true
14 | stdout_logfile=./log/%(program_name)s_%(process_num)02d_%(host_node_name)s.log
15 | stdout_logfile_maxbytes=1MB
16 | stdout_logfile_backups=1
17 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/start_localhost.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # go to script folder
4 | test_dir=$(dirname "$(readlink -f "$0")")
5 | cd $test_dir
6 |
7 | # clear log folder
8 | rm -rf log
9 | mkdir log
10 |
11 | # environmental variables for log file names
12 | export CUR_DATE=`date +'%y%m%d'`
13 | export CUR_TIME=`date +'%H%M%S'`
14 |
15 | # start firefox to get the Web UI
16 | firefox http://localhost:61000 &
17 |
18 | # start non-daemonized supervisor
19 | echo "start Supvisors on" `hostname`
20 | supervisord -c etc/supervisord_localhost.conf -n
21 |
--------------------------------------------------------------------------------
/supvisors/test/scripts/stop_all.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # directories
4 | SCRIPT_DIR=`dirname $(readlink -e $0)`
5 | TEST_DIR=`readlink -e $SCRIPT_DIR/..`
6 |
7 | # change working directory
8 | pushd .
9 | cd $TEST_DIR
10 |
11 | # stop all instances
12 | # multicast version not needed as supervisorctl is independent from that
13 | for host in ${@:-rocky51 rocky52}
14 | do
15 | echo "stop Supervisor on host" $host
16 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $TEST_DIR
17 | supervisorctl shutdown
18 | supervisorctl -c etc/supervisord_alt.conf shutdown"
19 | done
20 |
21 | # back to ref directory
22 | popd
23 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/rocky53/programs_rocky53.ini:
--------------------------------------------------------------------------------
1 | [program:scen1_sensor_acquisition_2]
2 | command=bin/scen1/sensor_acquisition.sh
3 | autostart=false
4 | killasgroup=true
5 | stopasgroup=true
6 | redirect_stderr=true
7 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
8 | stdout_logfile_backups=5
9 |
10 | [program:scen1_sensor_processing_2]
11 | command=bin/scen1/sensor_processing.sh
12 | autostart=false
13 | killasgroup=true
14 | stopasgroup=true
15 | redirect_stderr=true
16 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
17 | stdout_logfile_backups=5
18 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/rocky52/programs_rocky52.ini:
--------------------------------------------------------------------------------
1 | [program:scen1_sensor_acquisition_1]
2 | command=bin/scen1/sensor_acquisition.sh
3 | autostart=false
4 | killasgroup=true
5 | stopasgroup=true
6 | redirect_stderr=true
7 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
8 | stdout_logfile_backups=5
9 |
10 | [program:scen1_sensor_processing_1]
11 | command=bin/scen1/sensor_processing.sh
12 | autostart=false
13 | killasgroup=true
14 | stopasgroup=true
15 | redirect_stderr=true
16 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
17 | stdout_logfile_backups=5
18 |
19 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/common/group_services.ini:
--------------------------------------------------------------------------------
1 | [program:common_data_bus]
2 | command=zenity --info --text=%(program_name)s
3 | startsecs=10
4 | killasgroup=true
5 | stopasgroup=true
6 | redirect_stderr=true
7 | stdout_syslog=True
8 | stdout_logfile=log/%(program_name)s_%(host_node_name)s.log
9 | stdout_logfile_backups=5
10 |
11 | [program:scen3_internal_data_bus]
12 | command=zenity --info --text=%(program_name)s
13 | startsecs=10
14 | killasgroup=true
15 | stopasgroup=true
16 | redirect_stderr=true
17 | stdout_syslog=True
18 | stdout_logfile=log/%(program_name)s_%(host_node_name)s.log
19 | stdout_logfile_backups=5
20 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/my_movies/program_restart_application.ini:
--------------------------------------------------------------------------------
1 | [program:restart_application]
2 | command=bash -c 'python ./scripts/process_app.py -n %(program_name)s -x 25 && supvisorsctl -s http://localhost:60000 restart_application CONFIG %(group_name)s'
3 | autostart=false
4 | autorestart=unexpected
5 | startsecs=2
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s_out.log
11 | stdout_logfile_maxbytes=10KB
12 | stdout_logfile_backups=1
13 | stderr_logfile=./log/%(program_name)s_%(host_node_name)s_err.log
14 | stderr_logfile_maxbytes=10KB
15 | stderr_logfile_backups=1
16 |
--------------------------------------------------------------------------------
/supvisors/test/etc/common/my_movies/program_restart_process.ini:
--------------------------------------------------------------------------------
1 | [program:restart_process]
2 | command=bash -c 'python ./scripts/process_app.py -n %(program_name)s -x 15 && supvisorsctl -s http://localhost:60000 restart_process CONFIG %(group_name)s:%(program_name)s'
3 | autostart=false
4 | autorestart=false
5 | startsecs=2
6 | startretries=0
7 | exitcodes=0
8 | stopsignal=TERM
9 | stopwaitsecs=10
10 | stdout_logfile=./log/%(program_name)s_%(host_node_name)s_out.log
11 | stdout_logfile_maxbytes=10KB
12 | stdout_logfile_backups=1
13 | stderr_logfile=./log/%(program_name)s_%(host_node_name)s_err.log
14 | stderr_logfile_maxbytes=10KB
15 | stderr_logfile_backups=1
16 |
--------------------------------------------------------------------------------
/supvisors/test/etc/my_movies_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 1
6 | 0
7 |
8 |
9 | supv-01
10 | 1
11 |
12 |
13 | supv-01
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | SPHINXPROJ = Supvisors
8 | SOURCEDIR = .
9 | BUILDDIR = .build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # go to script folder
4 | test_dir=$(dirname "$(readlink -f "$0")")
5 |
6 | # environmental variables for log file names
7 | export CUR_DATE=`date +'%y%m%d'`
8 | export CUR_TIME=`date +'%H%M%S'`
9 |
10 | # start supervisor on remote machines
11 | for i in rocky51 rocky52 rocky53
12 | do
13 | echo "start Supvisors on" $i
14 | ssh $i "export DISPLAY=:0 ; cd $test_dir ; rm -rf log ; mkdir log
15 | export CUR_DATE=$CUR_DATE
16 | export CUR_TIME=$CUR_TIME
17 | supervisord -c etc/supervisord_distributed.conf"
18 | done
19 |
20 | # start firefox to get the Web UI
21 | firefox http://localhost:61000 &
22 |
23 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/start_mc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # go to script folder
4 | test_dir=$(dirname "$(readlink -f "$0")")
5 |
6 | # environmental variables for log file names
7 | export CUR_DATE=`date +'%y%m%d'`
8 | export CUR_TIME=`date +'%H%M%S'`
9 |
10 | # start supervisor on remote machines
11 | for i in rocky51 rocky52 rocky53
12 | do
13 | echo "start Supvisors on" $i
14 | ssh $i "export DISPLAY=:0 ; cd $test_dir ; rm -rf log ; mkdir log
15 | export CUR_DATE=$CUR_DATE
16 | export CUR_TIME=$CUR_TIME
17 | supervisord -c etc/supervisord_distributed_mc.conf -i $i"
18 | done
19 |
20 | # start firefox to get the Web UI
21 | firefox http://localhost:61000/?auto=True &
22 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # .readthedocs.yaml
2 | # Read the Docs configuration file
3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4 |
5 | # Required
6 | version: 2
7 |
8 | # Set the version of Python and other tools you might need
9 | build:
10 | os: ubuntu-lts-latest
11 | tools:
12 | python: "3.11"
13 |
14 | # Build documentation in the docs/ directory with Sphinx
15 | sphinx:
16 | configuration: docs/conf.py
17 |
18 | formats:
19 | - pdf
20 |
21 | # We recommend specifying your dependencies to enable reproducible builds:
22 | # https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
23 | python:
24 | install:
25 | - requirements: docs/requirements.txt
26 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/supervisord_localhost.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:61000
3 |
4 | [supervisord]
5 | logfile=log/supervisord.log
6 | logfile_backups=10
7 | loglevel=info
8 | pidfile=/tmp/supervisord.pid
9 | nodaemon=false
10 | umask=002
11 |
12 | [rpcinterface:supervisor]
13 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
14 |
15 | [supervisorctl]
16 | serverurl=http://localhost:61000
17 |
18 | [include]
19 | files = */programs_*.ini localhost/group_localhost.ini
20 |
21 | [rpcinterface:supvisors]
22 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
23 | rules_files = etc/supvisors_rules.xml
24 |
25 | [ctlplugin:supvisors]
26 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
27 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/supervisord_distributed.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:61000
3 |
4 | [supervisord]
5 | logfile=log/supervisord.log
6 | logfile_backups=10
7 | loglevel=info
8 | pidfile=/tmp/supervisord.pid
9 | nodaemon=false
10 | umask=002
11 |
12 | [rpcinterface:supervisor]
13 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
14 |
15 | [supervisorctl]
16 | serverurl=http://localhost:61000
17 |
18 | [include]
19 | files = %(host_node_name)s/*.ini
20 |
21 | [rpcinterface:supvisors]
22 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
23 | supvisors_list = supv01,supv02,supv03
24 | rules_files = etc/supvisors_rules.xml
25 |
26 | [ctlplugin:supvisors]
27 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
28 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/supervisord_server_mc.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:61000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_server.log
6 | pidfile=/tmp/supervisord_server.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:61000
13 |
14 | [include]
15 | files = common/*.ini server/*.ini
16 |
17 | [rpcinterface:supvisors]
18 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
19 | stereotypes = @SERVER
20 | multicast_group = 239.0.0.1:60001
21 | multicast_ttl = 1
22 | rules_files = etc/supvisors_rules_mc.xml
23 | core_identifiers = @SERVER
24 |
25 | [ctlplugin:supvisors]
26 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
27 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/supervisord_console_mc.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:62000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_console.log
6 | pidfile=/tmp/supervisord_console.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:62000
13 |
14 | [include]
15 | files = common/*.ini console/*.ini
16 |
17 | [rpcinterface:supvisors]
18 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
19 | stereotypes = @CONSOLE
20 | multicast_group = 239.0.0.1:60001
21 | multicast_ttl = 1
22 | rules_files = etc/supvisors_rules_mc.xml
23 | core_identifiers = @SERVER
24 |
25 | [ctlplugin:supvisors]
26 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
27 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/supervisord_distributed_mc.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:61000
3 |
4 | [supervisord]
5 | logfile=log/supervisord.log
6 | logfile_backups=10
7 | loglevel=info
8 | pidfile=/tmp/supervisord.pid
9 | nodaemon=false
10 | umask=002
11 |
12 | [rpcinterface:supervisor]
13 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
14 |
15 | [supervisorctl]
16 | serverurl=http://localhost:61000
17 |
18 | [include]
19 | files = %(host_node_name)s/*.ini
20 |
21 | [rpcinterface:supvisors]
22 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
23 | multicast_group = 239.0.0.1:61001
24 | rules_files = etc/supvisors_rules.xml
25 | auto_fence = True
26 |
27 | [ctlplugin:supvisors]
28 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
29 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/template_etc/console/programs_console.ini:
--------------------------------------------------------------------------------
1 | [program:scen3_chart_view]
2 | command=./bin/scen3/chart_view.sh
3 | autostart=false
4 | killasgroup=true
5 | stopasgroup=true
6 | redirect_stderr=true
7 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
8 | stdout_logfile_backups=5
9 |
10 | [program:scen3_item_control]
11 | command=./bin/scen3/item_control.sh
12 | autostart=false
13 | killasgroup=true
14 | stopasgroup=true
15 | redirect_stderr=true
16 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
17 | stdout_logfile_backups=5
18 |
19 | [program:scen3_check_internal_data_bus]
20 | command=./bin/scen3/check_internal_data_bus.sh
21 | autostart=false
22 | startsecs=0
23 | killasgroup=true
24 | stopasgroup=true
25 | redirect_stderr=true
26 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
27 | stdout_logfile_backups=5
28 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/configure.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # get consoles from Supvisors rules file
4 | RULES_FILE=etc/supvisors_rules.xml
5 |
6 | PY_ALIAS="from xml.etree.ElementTree import parse
7 | root = parse('$RULES_FILE').getroot()
8 | consoles = root.findtext('./alias[@name=\"consoles\"]')
9 | print(consoles.replace(',', ' '))
10 | "
11 |
12 | CONSOLES=`python3 -c "$PY_ALIAS"`
13 | NB_CONSOLES=`echo $CONSOLES | wc -w`
14 |
15 | # duplicate Scenario 3 HCI applications iaw the number of consoles
16 | # option -x is used to separate the definitions
17 | supvisors_breed -d etc -t template_etc -b scen3_hci=$NB_CONSOLES -x -v
18 |
19 | # assign one HCI application per console
20 | for console in $CONSOLES
21 | do
22 | mkdir -p etc/console/$console
23 | FIRST=`ls etc/console/group*.ini | head -1`
24 | mv -f $FIRST etc/console/$console
25 | done
26 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/start_localhost_mc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # go to script folder
4 | test_dir=$(dirname "$(readlink -f "$0")")
5 |
6 | # environmental variables for log file names
7 | export CUR_DATE=`date +'%y%m%d'`
8 | export CUR_TIME=`date +'%H%M%S'`
9 | export DISPLAY=:0
10 |
11 | # set default hosts if not provided in command line
12 | HOST=`hostname`
13 |
14 | # clear logs / start server + console on each host
15 | cd $test_dir
16 | rm -rf log ; mkdir log
17 |
18 | echo "start Supvisors on $HOST as server_1"
19 | export IDENTIFIER=server_1
20 | supervisord -c etc/supervisord_server_mc.conf -i $IDENTIFIER
21 |
22 | echo "start Supvisors on $HOST as console_1"
23 | export IDENTIFIER=console_1
24 | supervisord -c etc/supervisord_console_mc.conf -i $IDENTIFIER
25 |
26 | # start firefox to get the Web UI
27 | firefox http://localhost:61000?auto=true &
28 |
--------------------------------------------------------------------------------
/supvisors/ui/css/proc_instance.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Supvisors Process Instance page style
19 | */
20 |
21 | /* process table bottom has 2 lines */
22 | .process_table tfoot>tr:nth-child(1) th {
23 | bottom: 20px;
24 | }
25 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/start_localhost.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # go to script folder
4 | test_dir=$(dirname "$(readlink -f "$0")")
5 |
6 | # environmental variables for log file names
7 | export CUR_DATE=`date +'%y%m%d'`
8 | export CUR_TIME=`date +'%H%M%S'`
9 | export DISPLAY=:0
10 |
11 | # set default hosts if not provided in command line
12 | HOST=`hostname`
13 |
14 | # clear logs / start server + console on each host
15 | cd $test_dir
16 | rm -rf log ; mkdir log
17 |
18 | echo "start Supvisors on $HOST as server_1"
19 | export IDENTIFIER=server_1
20 | supervisord -c etc/supervisord_server_localhost.conf -i $IDENTIFIER
21 |
22 | echo "start Supvisors on $HOST as console_1"
23 | export IDENTIFIER=console_1
24 | supervisord -c etc/supervisord_console_localhost.conf -i $IDENTIFIER
25 |
26 | # start firefox to get the Web UI
27 | firefox http://localhost:61000?auto=true &
28 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/supervisord_server_mc.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:61000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_server.log
6 | pidfile=/tmp/supervisord_server.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:61000
13 |
14 | [include]
15 | files = common/*.ini server/*.ini
16 |
17 | [rpcinterface:supvisors]
18 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
19 | stereotypes = @SERVER
20 | multicast_group = 239.0.0.1:60001
21 | multicast_ttl = 1
22 | rules_files = etc/supvisors_rules_mc.xml
23 | core_identifiers = @SERVER
24 | synchro_timeout = 60
25 | stats_periods = 10,100
26 |
27 | [ctlplugin:supvisors]
28 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
29 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/console/programs_console.ini:
--------------------------------------------------------------------------------
1 | [program:scen3_chart_view]
2 | command = ./bin/scen3/chart_view.sh
3 | autostart = false
4 | killasgroup = true
5 | stopasgroup = true
6 | redirect_stderr = true
7 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
8 | stdout_logfile_backups = 5
9 |
10 | [program:scen3_item_control]
11 | command = ./bin/scen3/item_control.sh
12 | autostart = false
13 | killasgroup = true
14 | stopasgroup = true
15 | redirect_stderr = true
16 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
17 | stdout_logfile_backups = 5
18 |
19 | [program:scen3_check_internal_data_bus]
20 | command = ./bin/scen3/check_internal_data_bus.sh
21 | autostart = false
22 | startsecs = 0
23 | killasgroup = true
24 | stopasgroup = true
25 | redirect_stderr = true
26 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
27 | stdout_logfile_backups = 5
28 |
29 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/supervisord_server.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:61000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_server.log
6 | pidfile=/tmp/supervisord_server.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:61000
13 |
14 | [include]
15 | files = common/*.ini server/*.ini
16 |
17 | [rpcinterface:supvisors]
18 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
19 | supvisors_list = supv01:61000,supv02:61000,supv03:61000,supv01:62000,supv02:62000,supv03:62000
20 | rules_files = etc/supvisors_rules.xml
21 | core_identifiers = server_1,server_2,server_3
22 |
23 | [ctlplugin:supvisors]
24 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
25 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/supervisord_console.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:62000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_console.log
6 | pidfile=/tmp/supervisord_console.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:62000
13 |
14 | [include]
15 | files = common/*.ini console/*.ini
16 |
17 | [rpcinterface:supvisors]
18 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
19 | supvisors_list = supv01:61000,supv02:61000,supv03:61000,supv01:62000,supv02:62000,supv03:62000
20 | rules_files = etc/supvisors_rules.xml
21 | core_identifiers = server_1,server_2,server_3
22 |
23 | [ctlplugin:supvisors]
24 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
25 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # go to script folder
4 | test_dir=$(dirname "$(readlink -f "$0")")
5 |
6 | # set default hosts if not provided in command line
7 | HOSTS=${@:-rocky51 rocky52 rocky53}
8 |
9 | # clear logs / configure / start server + console on each host
10 | for host in $HOSTS
11 | do
12 | x=`echo "$host" | tail -c 2`
13 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $test_dir
14 | rm -rf log ; mkdir log
15 | ./configure.sh
16 | export DISPLAY=:0
17 | echo \"start Supvisors on $host as server_$x\"
18 | export IDENTIFIER=server_$x
19 | supervisord -c etc/supervisord_server.conf -i \$IDENTIFIER
20 | echo \"start Supvisors on $host as console_$x\"
21 | export IDENTIFIER=console_$x
22 | supervisord -c etc/supervisord_console.conf -i \$IDENTIFIER"
23 | done
24 |
25 | # start firefox to get the Web UI
26 | firefox http://localhost:61000?auto=True &
27 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/start_mc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # go to script folder
4 | test_dir=$(dirname "$(readlink -f "$0")")
5 |
6 | # set default hosts if not provided in command line
7 | HOSTS=${@:-rocky51 rocky52 rocky53}
8 |
9 | # clear logs / configure / start server + console on each host
10 | for host in $HOSTS
11 | do
12 | x=`echo "$host" | tail -c 2`
13 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $test_dir
14 | rm -rf log ; mkdir log
15 | ./configure.sh
16 | export DISPLAY=:0
17 | echo \"start Supvisors on $host as server_$x\"
18 | export IDENTIFIER=server_$x
19 | supervisord -c etc/supervisord_server_mc.conf -i \$IDENTIFIER
20 | echo \"start Supvisors on $host as console_$x\"
21 | export IDENTIFIER=console_$x
22 | supervisord -c etc/supervisord_console_mc.conf -i \$IDENTIFIER"
23 | done
24 |
25 | # start firefox to get the Web UI
26 | firefox http://localhost:61000?auto=True &
27 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | |Supvisors|: A Control System for Distributed Applications
2 | ==========================================================
3 |
4 | |Supvisors| is a Control System for Distributed Applications, based on multiple instances of |Supervisor|.
5 |
6 | .. toctree::
7 | :maxdepth: 2
8 | :caption: Contents
9 |
10 | introduction.rst
11 | configuration.rst
12 | dashboard.rst
13 | xml_rpc.rst
14 | flask.rst
15 | supervisorctl.rst
16 | event_interface.rst
17 | special.rst
18 | troubleshooting.rst
19 | faq.rst
20 |
21 | .. toctree::
22 | :maxdepth: 2
23 | :caption: Use Cases
24 |
25 | scenario_1.rst
26 | scenario_2.rst
27 | scenario_3.rst
28 |
29 | .. toctree::
30 | :maxdepth: 3
31 | :caption: Release History
32 |
33 | CHANGES.md
34 |
35 |
36 | Indices and tables
37 | ------------------
38 |
39 | * :ref:`genindex`
40 | * :ref:`modindex`
41 | * :ref:`search`
42 |
43 | .. include:: common.rst
44 |
--------------------------------------------------------------------------------
/supvisors/external_com/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | # ======================================================================
5 | # Copyright 2023 Julien LE CLEACH
6 | #
7 | # Licensed under the Apache License, Version 2.0 (the "License");
8 | # you may not use this file except in compliance with the License.
9 | # You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing, software
14 | # distributed under the License is distributed on an "AS IS" BASIS,
15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | # See the License for the specific language governing permissions and
17 | # limitations under the License.
18 | # ======================================================================
19 |
20 | # expose the useful structure
21 | from .eventinterface import create_external_publisher, EventPublisherInterface
22 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/supvisors_rules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2
6 | true
7 | 2
8 |
9 |
10 |
11 |
12 | 1
13 | CONTINUE
14 |
15 |
16 |
17 | model_scenario_1
18 |
19 |
20 |
21 | model_scenario_1
22 | 1
23 | true
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/supervisord_server.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:61000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_server.log
6 | pidfile=/tmp/supervisord_server.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:61000
13 |
14 | [include]
15 | files = common/*.ini server/*.ini
16 |
17 | [rpcinterface:supvisors]
18 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
19 | supvisors_list = supv01:61000,supv02:61000,supv03:61000,supv01:62000,supv02:62000,supv03:62000
20 | rules_files = etc/supvisors_rules.xml
21 | core_identifiers = server_1,server_2,server_3
22 | synchro_options=USER,TIMEOUT
23 | synchro_timeout=60
24 | stats_periods = 10,100
25 |
26 | [ctlplugin:supvisors]
27 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
28 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/supervisord_console.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:62000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_console.log
6 | pidfile=/tmp/supervisord_console.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:62000
13 |
14 | [include]
15 | files = common/*.ini console/*.ini
16 | console/%(ENV_IDENTIFIER)s/*.ini
17 |
18 | [rpcinterface:supvisors]
19 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
20 | supvisors_list = supv01:61000,supv02:61000,supv03:61000,supv01:62000,supv02:62000,supv03:62000
21 | rules_files = etc/supvisors_rules.xml
22 | core_identifiers = server_1,server_2,server_3
23 | synchro_options=USER
24 | synchro_timeout=60
25 |
26 | [ctlplugin:supvisors]
27 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
28 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/supervisord_console_mc.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:62000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_console.log
6 | pidfile=/tmp/supervisord_console.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:62000
13 |
14 | [include]
15 | files = common/*.ini console/*.ini
16 | console/%(ENV_IDENTIFIER)s/*.ini
17 |
18 | [rpcinterface:supvisors]
19 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
20 | software_name = Scenario 3 SW
21 | software_icon = ../../../ui/img/icon.png
22 | stereotypes = @CONSOLE
23 | multicast_group = 239.0.0.1:60001
24 | multicast_ttl = 1
25 | rules_files = etc/supvisors_rules_mc.xml
26 | core_identifiers = @SERVER
27 | synchro_options=USER,TIMEOUT
28 | synchro_timeout=60
29 |
30 | [ctlplugin:supvisors]
31 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
32 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/etc/supervisord_server_localhost.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:61000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_server.log
6 | pidfile=/tmp/supervisord_server.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:61000
13 |
14 | [include]
15 | files = scen*1/*/prog* scen*1/localhost/* scen*2/server/prog* scen*2/server/group*01* scen*3/common/* scen*3/server/*
16 |
17 | [rpcinterface:supvisors]
18 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
19 | supvisors_list = supv01:61000,supv01:62000
20 | rules_files = etc/scenario_1/supvisors_rules.xml
21 | etc/scenario_2/supvisors_rules.xml
22 | etc/scenario_3/supvisors_rules.xml
23 | core_identifiers = server_1
24 | stats_periods = 10,60,3600
25 |
26 | [ctlplugin:supvisors]
27 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
28 |
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist =
3 | cover,py39,py310,py311,py312,py313,docs
4 |
5 | [testenv:common]
6 | deps =
7 | supervisor >= 4.2.4
8 | pyzmq >= 25.1.1
9 | psutil >= 5.9.0
10 | matplotlib >= 3.5.1
11 | lxml >= 4.8.0
12 | pyparsing >= 2.4.7, < 3
13 | pytest
14 | pytest-asyncio < 0.22
15 | pytest-mock
16 | commands =
17 | pytest
18 |
19 |
20 | [testenv]
21 | deps =
22 | {[testenv:common]deps}
23 | flask-restx >= 1.2.0, < 1.3
24 | websockets >= 11.0.3, < 14
25 | commands = {[testenv:common]commands}
26 |
27 |
28 | [testenv:cover]
29 | deps =
30 | {[testenv]deps}
31 | pytest-cov
32 | commands =
33 | pytest --cov=supvisors --cov-report=xml --cov-report=term-missing
34 |
35 |
36 | [testenv:docs]
37 | deps =
38 | pyzmq >= 25.1.1
39 | websockets >= 11.0.3, < 14
40 | sphinx == 7.2.6
41 | renku-sphinx-theme == 0.4.0
42 | myst-parser == 2.0.0
43 | allowlist_externals = make
44 | commands =
45 | make -C docs html BUILDDIR={envtmpdir} "SPHINXOPTS=-W -E"
46 |
--------------------------------------------------------------------------------
/supvisors/test/scripts/start_all.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # directories
4 | SCRIPTS_DIR=`dirname $(readlink -e $0)`
5 | TEST_DIR=`readlink -e $SCRIPTS_DIR/..`
6 |
7 | # start all instances
8 | for host in ${@:-rocky51 rocky52}
9 | do
10 | if [ "$host" == "rocky51" ]
11 | then
12 | echo "start Supervisor supv-01 on $host"
13 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $TEST_DIR ; rm -rf log/*
14 | export DISPLAY=:0
15 | export IDENTIFIER=supv-01
16 | supervisord -i supv-01"
17 | echo "start Supervisor supv-03 on $host"
18 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $TEST_DIR
19 | export DISPLAY=:0
20 | export IDENTIFIER=supv-03
21 | supervisord -c etc/supervisord_alt.conf"
22 | else
23 | echo "start Supervisor on $host"
24 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $TEST_DIR ; rm -rf log/*
25 | export DISPLAY=:0
26 | supervisord"
27 | fi
28 | done
29 |
30 | cd $TEST_DIR
31 | pwd
32 | sleep 1
33 | tail -f -n +1 log/supervisord.log
34 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/etc/supervisord_server_mc.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:61000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_server.log
6 | pidfile=/tmp/supervisord_server.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:61000
13 |
14 | [include]
15 | files = scen*1/%(host_node_name)s/*
16 | scen*2/server/*
17 | scen*3/common/* scen*3/server/*
18 |
19 | [rpcinterface:supvisors]
20 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
21 | stereotypes = @SERVER
22 | multicast_group = 239.0.0.1:61500
23 | multicast_ttl = 1
24 | rules_files = etc/scenario_1/supvisors_rules.xml
25 | etc/scenario_2/supvisors_rules_mc.xml
26 | etc/scenario_3/supvisors_rules_mc.xml
27 | core_identifiers = @SERVER
28 | synchro_options=USER,TIMEOUT
29 | synchro_timeout=60
30 |
31 | [ctlplugin:supvisors]
32 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
33 |
--------------------------------------------------------------------------------
/supvisors/__init__.py:
--------------------------------------------------------------------------------
1 | # ======================================================================
2 | # Copyright 2023 Julien LE CLEACH
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ======================================================================
16 |
17 | import os
18 |
19 | # get Supvisors version from file
20 | here = os.path.abspath(os.path.dirname(__file__))
21 | version_txt = os.path.join(here, 'version.txt')
22 | with open(version_txt, 'r') as ver:
23 | supvisors_version = ver.read().split('=')[1].strip()
24 |
--------------------------------------------------------------------------------
/supvisors/ui/css/instance.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Supvisors Instance pages style
19 | */
20 |
21 | /* Header status part */
22 | #instance_status table.status img {
23 | width: 25px;
24 | position: relative;
25 | top: 3px;
26 | }
27 |
28 | #instance_status th span.master {
29 | font-size: 1.6em;
30 | position: relative;
31 | bottom: 0.1em;
32 | }
33 |
34 | .hmode {
35 | font-size: 1.2em;
36 | }
37 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # go to script folder
4 | test_dir=$(dirname "$(readlink -f "$0")")
5 |
6 | # environmental variables for log file names
7 | export CUR_DATE=`date +'%y%m%d'`
8 | export CUR_TIME=`date +'%H%M%S'`
9 |
10 | # set default hosts if not provided in command line
11 | HOSTS=${@:-rocky51 rocky52 rocky53}
12 |
13 | # clear logs / start server + console on each host
14 | for host in $HOSTS
15 | do
16 | x=`echo "$host" | tail -c 2`
17 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $test_dir
18 | rm -rf log ; mkdir log
19 | export DISPLAY=:0
20 | export CUR_DATE=$CUR_DATE
21 | export CUR_TIME=$CUR_TIME
22 | echo \"start Supvisors on $host as server_$x\"
23 | export IDENTIFIER=server_$x
24 | supervisord -c etc/supervisord_server.conf -i \$IDENTIFIER
25 | echo \"start Supvisors on $host as console_$x\"
26 | export IDENTIFIER=console_$x
27 | supervisord -c etc/supervisord_console.conf -i \$IDENTIFIER"
28 | done
29 |
30 | # start firefox to get the Web UI
31 | firefox http://localhost:61000?auto=true &
32 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/etc/supervisord_console_mc.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:62000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_console.log
6 | pidfile=/tmp/supervisord_console.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:62000
13 |
14 | [include]
15 | files = scen*1/%(host_node_name)s/*
16 | scen*2/console/*
17 | scen*3/common/* scen*3/console/* scen*3/console/%(ENV_IDENTIFIER)s/*
18 |
19 | [rpcinterface:supvisors]
20 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
21 | stereotypes = @CONSOLE
22 | multicast_group = 239.0.0.1:61500
23 | multicast_ttl = 1
24 | rules_files = etc/scenario_1/supvisors_rules.xml
25 | etc/scenario_2/supvisors_rules_mc.xml
26 | etc/scenario_3/supvisors_rules_mc.xml
27 | core_identifiers = @SERVER
28 | synchro_options=USER,TIMEOUT
29 | synchro_timeout=60
30 |
31 | [ctlplugin:supvisors]
32 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
33 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/start_mc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # go to script folder
4 | test_dir=$(dirname "$(readlink -f "$0")")
5 |
6 | # environmental variables for log file names
7 | export CUR_DATE=$(date +'%y%m%d')
8 | export CUR_TIME=$(date +'%H%M%S')
9 |
10 | # set default hosts if not provided in command line
11 | HOSTS=${@:-rocky51 rocky52 rocky53}
12 |
13 | # clear logs / start server + console on each host
14 | for host in $HOSTS
15 | do
16 | x=$(echo "$host" | tail -c 2)
17 | ping -c 1 "$host" 2>&1 >/dev/null && ssh "$host" "cd $test_dir
18 | rm -rf log ; mkdir log
19 | export DISPLAY=:0
20 | export CUR_DATE=$CUR_DATE
21 | export CUR_TIME=$CUR_TIME
22 | echo \"start Supvisors on $host as server_$x\"
23 | export IDENTIFIER=server_$x
24 | supervisord -c etc/supervisord_server_mc.conf -i \$IDENTIFIER
25 | echo \"start Supvisors on $host as console_$x\"
26 | export IDENTIFIER=console_$x
27 | supervisord -c etc/supervisord_console_mc.conf -i \$IDENTIFIER"
28 | done
29 |
30 | # start firefox to get the Web UI
31 | firefox http://localhost:61000?auto=True &
32 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/etc/supervisord_console_localhost.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:62000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_console.log
6 | pidfile=/tmp/supervisord_console.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:62000
13 |
14 | [include]
15 | files = scen*1/%(host_node_name)s/* scen*2/console/prog* scen*2/console/group*01* scen*3/common/* scen*3/console/* scen*3/console/console_1/*
16 |
17 | [rpcinterface:supvisors]
18 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
19 | software_name = Gathering
20 | software_icon = ../../../ui/img/icon.png
21 | supvisors_list = supv01:61000,supv01:62000
22 | rules_files = etc/scenario_1/supvisors_rules.xml
23 | etc/scenario_2/supvisors_rules.xml
24 | etc/scenario_3/supvisors_rules.xml
25 | core_identifiers = server_1
26 |
27 | [ctlplugin:supvisors]
28 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
29 |
--------------------------------------------------------------------------------
/supvisors/test/scripts/start_all_mc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # directories
4 | SCRIPTS_DIR=`dirname $(readlink -e $0)`
5 | TEST_DIR=`readlink -e $SCRIPTS_DIR/..`
6 |
7 | # start all instances
8 | for host in ${@:-rocky51 rocky52}
9 | do
10 | if [ "$host" == "rocky51" ]
11 | then
12 | echo "start Supervisor supv-01 on $host"
13 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $TEST_DIR ; rm -rf log/*
14 | export DISPLAY=:0
15 | export IDENTIFIER=supv-01
16 | supervisord -i supv-01 -c etc/supervisord_mc.conf"
17 | echo "start Supervisor supv-03 on $host"
18 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $TEST_DIR
19 | export DISPLAY=:0
20 | export IDENTIFIER=supv-03
21 | supervisord -i supv-03 -c etc/supervisord_alt_mc.conf"
22 | else
23 | echo "start Supervisor on $host"
24 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $TEST_DIR ; rm -rf log/*
25 | export DISPLAY=:0
26 | supervisord -c etc/supervisord_mc.conf"
27 | fi
28 | done
29 |
30 | cd $TEST_DIR
31 | pwd
32 | sleep 1
33 | tail -f -n +1 log/supervisord.log
34 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/SupvisorsAnyInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 | /**
20 | * The Interface SupvisorsAnyInfo.
21 | *
22 | * It is used to identify a key to sort typed structures into a map.
23 | */
24 | public interface SupvisorsAnyInfo {
25 |
26 | /**
27 | * The method returns the name to be used as a key map.
28 | *
29 | * @return String: the key.
30 | */
31 | String getName();
32 | }
33 |
--------------------------------------------------------------------------------
/supvisors/test/etc/supervisord_alt_mc.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:30000
3 | ;username=cliche
4 | ;password=p@$$w0rd
5 |
6 | [supervisord]
7 | logfile=./log/supervisord_alt.log
8 | loglevel=info
9 | pidfile=/tmp/supervisord_alt.pid
10 |
11 | [rpcinterface:supervisor]
12 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
13 |
14 | [supervisorctl]
15 | serverurl=http://localhost:30000
16 |
17 | [include]
18 | files = common/*/*.ini %(ENV_IDENTIFIER)s/*.ini
19 |
20 | [rpcinterface:supvisors]
21 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
22 | multicast_group = 239.0.0.1:60001
23 | multicast_ttl = 1
24 | rules_files = etc/my_movies*.xml
25 | auto_fence = false
26 | synchro_options = LIST,CORE,TIMEOUT,USER
27 | synchro_timeout = 20
28 | inactivity_ticks = 3
29 | starting_strategy = CONFIG
30 | conciliation_strategy = USER
31 | stats_enabled = true
32 | stats_periods = 5,60,600
33 | stats_histo = 100
34 | stats_irix_mode = true
35 | logfile = AUTO
36 |
37 | [ctlplugin:supvisors]
38 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
39 |
--------------------------------------------------------------------------------
/supvisors/test/scripts/evt_listener.py:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Adapted from Supervisor documentation
4 | # http://supervisord.org/events.html#example-event-listener-implementation
5 |
6 | import sys
7 |
8 |
9 | def write_stdout(s):
10 | # only eventlistener protocol messages may be sent to stdout
11 | sys.stdout.write(s)
12 | sys.stdout.flush()
13 |
14 |
15 | def write_stderr(s):
16 | sys.stderr.write(s)
17 | sys.stderr.flush()
18 |
19 |
20 | def main():
21 | while 1:
22 | # transition from ACKNOWLEDGED to READY
23 | write_stdout('READY\n')
24 | # read header line and print it to stderr
25 | line = sys.stdin.readline()
26 | write_stderr(line)
27 | # read event payload and print it to stderr
28 | headers = dict([x.split(':') for x in line.split()])
29 | data = sys.stdin.read(int(headers['len']))
30 | if headers['eventname'] != 'REMOTE_COMMUNICATION':
31 | write_stderr(data)
32 | # transition from READY to ACKNOWLEDGED
33 | write_stdout('RESULT 2\nOK')
34 |
35 |
36 | if __name__ == '__main__':
37 | main()
38 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/etc/supervisord_server.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:61000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_server.log
6 | pidfile=/tmp/supervisord_server.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:61000
13 |
14 | [include]
15 | files = scen*1/%(host_node_name)s/*
16 | scen*2/server/*
17 | scen*3/common/*
18 | scen*3/server/*
19 |
20 | [rpcinterface:supvisors]
21 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
22 | supvisors_list = supv01:61000,supv02:61000,supv03:61000,supv01:62000,supv02:62000,supv03:62000
23 | rules_files = etc/scenario_1/supvisors_rules.xml
24 | etc/scenario_2/supvisors_rules.xml
25 | etc/scenario_3/supvisors_rules.xml
26 | core_identifiers = server_1,server_2,server_3
27 | stats_periods = 10,60,3600
28 | stats_irix_mode = true
29 |
30 | [ctlplugin:supvisors]
31 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
32 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # go to script folder
4 | test_dir=$(dirname "$(readlink -f "$0")")
5 |
6 | # set default hosts if not provided in command line
7 | HOSTS=${@:-rocky51 rocky52 rocky53}
8 |
9 | # configure 3 applications
10 | SRV_CONFIG_CMD="supvisors_breed -d etc -t template_etc -p server/*.ini -b scen2_srv=3 -x -v"
11 | HCI_CONFIG_CMD="supvisors_breed -d etc -t template_etc -p console/*ini -b scen2_hci=3 -x -v"
12 |
13 | # clear logs / configure / start server + console on each host
14 | for host in $HOSTS
15 | do
16 | x=`echo "$host" | tail -c 2`
17 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $test_dir
18 | rm -rf log ; mkdir log
19 | $SRV_CONFIG_CMD
20 | $HCI_CONFIG_CMD
21 | export DISPLAY=:0
22 | echo \"start Supvisors on $host as server_$x\"
23 | export IDENTIFIER=server_$x
24 | supervisord -c etc/supervisord_server.conf -i \$IDENTIFIER
25 | echo \"start Supvisors on $host as console_$x\"
26 | export IDENTIFIER=console_$x
27 | supervisord -c etc/supervisord_console.conf -i \$IDENTIFIER"
28 | done
29 |
30 | # start firefox to get the Web UI
31 | firefox http://localhost:61000 &
32 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/start_mc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # go to script folder
4 | test_dir=$(dirname "$(readlink -f "$0")")
5 |
6 | # set default hosts if not provided in command line
7 | HOSTS=${@:-rocky51 rocky52 rocky53}
8 |
9 | # configure 3 applications
10 | SRV_CONFIG_CMD="supvisors_breed -d etc -t template_etc -p server/*.ini -b scen2_srv=3 -x -v"
11 | HCI_CONFIG_CMD="supvisors_breed -d etc -t template_etc -p console/*ini -b scen2_hci=3 -x -v"
12 |
13 | # clear logs / configure / start server + console on each host
14 | for host in $HOSTS
15 | do
16 | x=`echo "$host" | tail -c 2`
17 | ping -c 1 $host 2>&1 >/dev/null && ssh $host "cd $test_dir
18 | rm -rf log ; mkdir log
19 | $SRV_CONFIG_CMD
20 | $HCI_CONFIG_CMD
21 | export DISPLAY=:0
22 | echo \"start Supvisors on $host as server_$x\"
23 | export IDENTIFIER=server_$x
24 | supervisord -c etc/supervisord_server_mc.conf -i \$IDENTIFIER
25 | echo \"start Supvisors on $host as console_$x\"
26 | export IDENTIFIER=console_$x
27 | supervisord -c etc/supervisord_console_mc.conf -i \$IDENTIFIER"
28 | done
29 |
30 | # start firefox to get the Web UI
31 | firefox http://localhost:61000 &
32 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/StartingFailureStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 |
20 | /**
21 | * The StartingFailureStrategy enumeration.
22 | */
23 | public enum StartingFailureStrategy {
24 | ABORT(0),
25 | STOP(1),
26 | CONTINUE(2);
27 |
28 | /** The strategy code. */
29 | private int strategyCode;
30 |
31 | /** The constructor links the state code to the state name. */
32 | private StartingFailureStrategy(final int strategyCode) {
33 | this.strategyCode = strategyCode;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/DistributionRule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 |
20 | /**
21 | * The DistributionRule enumeration.
22 | */
23 | public enum DistributionRule {
24 | ALL_INSTANCES(0),
25 | SINGLE_INSTANCE(1),
26 | SINGLE_NODE(2);
27 |
28 | /** The distribution code. */
29 | private int distributionCode;
30 |
31 | /** The constructor links the state code to the state name. */
32 | private DistributionRule(final int distributionCode) {
33 | this.distributionCode = distributionCode;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/SupvisorsFailureStrategies.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 |
20 | /**
21 | * The SupvisorsFailureStrategies enumeration.
22 | */
23 | public enum SupvisorsFailureStrategies {
24 | CONTINUE(0),
25 | RESYNC(1),
26 | SHUTDOWN(2);
27 |
28 | /** The strategy code. */
29 | private int strategyCode;
30 |
31 | /** The constructor links the state code to the state name. */
32 | private SupvisorsFailureStrategies(final int strategyCode) {
33 | this.strategyCode = strategyCode;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/etc/supervisord_console.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:62000
3 |
4 | [supervisord]
5 | logfile=log/supervisord_console.log
6 | pidfile=/tmp/supervisord_console.pid
7 |
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 |
11 | [supervisorctl]
12 | serverurl=http://localhost:62000
13 |
14 | [include]
15 | files = scen*1/%(host_node_name)s/*
16 | scen*2/console/*
17 | scen*3/common/*
18 | scen*3/console/*
19 | scen*3/console/%(ENV_IDENTIFIER)s/*
20 |
21 | [rpcinterface:supvisors]
22 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
23 | software_name = Gathering
24 | software_icon = ../../../ui/img/icon.png
25 | supvisors_list = supv01:61000,supv02:61000,supv03:61000,supv01:62000,supv02:62000,supv03:62000
26 | rules_files = etc/scenario_1/supvisors_rules.xml
27 | etc/scenario_2/supvisors_rules.xml
28 | etc/scenario_3/supvisors_rules.xml
29 | core_identifiers = server_1,server_2,server_3
30 |
31 | [ctlplugin:supvisors]
32 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
33 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/ConciliationStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 |
20 | /**
21 | * The ConciliationStrategy enumeration.
22 | */
23 | public enum ConciliationStrategy {
24 | SENICIDE(0),
25 | INFANTICIDE(1),
26 | USER(2),
27 | STOP(3),
28 | RESTART(4),
29 | RUNNING_FAILURE(5);
30 |
31 | /** The strategy code. */
32 | private int strategyCode;
33 |
34 | /** The constructor links the state code to the state name. */
35 | private ConciliationStrategy(final int strategyCode) {
36 | this.strategyCode = strategyCode;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/StartingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 |
20 | /**
21 | * The StartingStrategy enumeration.
22 | */
23 | public enum StartingStrategy {
24 | CONFIG(0),
25 | LESS_LOADED(1),
26 | MOST_LOADED(2),
27 | LOCAL(3),
28 | LESS_LOADED_NODE(4),
29 | MOST_LOADED_NODE(5);
30 |
31 | /** The strategy code. */
32 | private int strategyCode;
33 |
34 | /** The constructor links the strategy code to the strategy name. */
35 | private StartingStrategy(final int strategyCode) {
36 | this.strategyCode = strategyCode;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/RunningFailureStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 |
20 | /**
21 | * The RunningFailureStrategy enumeration.
22 | */
23 | public enum RunningFailureStrategy {
24 | CONTINUE(0),
25 | RESTART_PROCESS(1),
26 | STOP_APPLICATION(2),
27 | RESTART_APPLICATION(3),
28 | SHUTDOWN(4),
29 | RESTART(5);
30 |
31 | /** The strategy code. */
32 | private int strategyCode;
33 |
34 | /** The constructor links the state code to the state name. */
35 | private RunningFailureStrategy(final int strategyCode) {
36 | this.strategyCode = strategyCode;
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/supvisors/test/etc/supervisord_alt.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:30000
3 | ;username=cliche
4 | ;password=p@$$w0rd
5 |
6 | [supervisord]
7 | logfile=./log/supervisord_alt.log
8 | loglevel=info
9 | pidfile=/tmp/supervisord_alt.pid
10 |
11 | [rpcinterface:supervisor]
12 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
13 |
14 | [supervisorctl]
15 | serverurl=http://localhost:30000
16 |
17 | [include]
18 | files = common/*/*.ini
19 | %(ENV_IDENTIFIER)s/*.ini
20 |
21 | [rpcinterface:supvisors]
22 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
23 | supvisors_list = 17.0.1.11:60000,supv02:60000,192.168.1.70
24 | stereotypes = third
25 | rules_files = etc/my_movies*.xml
26 | auto_fence = false
27 | synchro_options = LIST,CORE,TIMEOUT,USER
28 | synchro_timeout = 30
29 | inactivity_ticks = 3
30 | core_identifiers = supv-01,supv-03
31 | starting_strategy = CONFIG
32 | conciliation_strategy = USER
33 | stats_enabled = true
34 | stats_periods = 5,60,600
35 | stats_histo = 100
36 | stats_irix_mode = false
37 | logfile = AUTO
38 | ;logfile = ./log/supvisors_alt.log
39 | ;logfile_maxbytes = 50MB
40 | ;logfile_backups = 10
41 | ;loglevel = debug
42 |
43 | [ctlplugin:supvisors]
44 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
45 |
--------------------------------------------------------------------------------
/supvisors/ui/css/conciliation.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Supvisors Conciliation page
19 | */
20 |
21 | /* Contents part */
22 | #index_contents {
23 | display: flex;
24 | flex: 1;
25 | overflow: auto;
26 | padding: 10px;
27 | }
28 |
29 | /* update the background of the global strategies box */
30 | div.strategies {
31 | background-image: linear-gradient(180deg, var(--light2-color), var(--light1-color));
32 | }
33 |
34 | div.strategies div.button_group {
35 | background-image: none;
36 | }
37 |
38 | div.strategies div.button_group:not(:first-child) {
39 | padding-top: 0;
40 | }
41 |
42 | /* update the area of the local strategies box */
43 | div.local_strategies div {
44 | padding: 1px 3px;
45 | }
46 |
--------------------------------------------------------------------------------
/docs/common.rst:
--------------------------------------------------------------------------------
1 | .. |Supvisors| replace:: **Supvisors**
2 | .. |Supervisor| replace:: Supervisor_
3 | .. |psutil| replace:: psutil_
4 | .. |lxml| replace:: lxml_
5 | .. |Flask-RESTX| replace:: Flask-RESTX_
6 | .. |Flask| replace:: Flask_
7 | .. |PyZMQ| replace:: PyZMQ_
8 | .. |ZeroMQ| replace:: ZeroMQ_
9 | .. |Websockets| replace:: websockets_
10 |
11 | .. |start| image:: images/start_button.png
12 | :alt: Start button
13 |
14 | .. |stop| image:: images/stop_button.png
15 | :alt: Stop button
16 |
17 | .. |restart| image:: images/restart_button.png
18 | :alt: Restart button
19 |
20 | .. |shutdown| image:: images/shutdown_button.png
21 | :alt: Shutdown button
22 |
23 | .. |refresh| image:: images/refresh_button.png
24 | :alt: Refresh button
25 |
26 | .. |autorefresh| image:: images/autorefresh_button.png
27 | :alt: Refresh button
28 |
29 | .. |star| image:: images/star_button.png
30 | :alt: Star button
31 |
32 | .. |br| raw:: html
33 |
34 |
35 |
36 | .. _Supervisor: http://supervisord.org
37 | .. _psutil: https://pypi.python.org/pypi/psutil
38 | .. _matplotlib: https://matplotlib.org
39 | .. _lxml: https://lxml.de
40 | .. _Flask-RESTX: https://flask-restx.readthedocs.io
41 | .. _Flask: https://flask.palletsprojects.com
42 | .. _PyZMQ: https://pyzmq.readthedocs.io
43 | .. _ZeroMQ: https://zeromq.org
44 | .. _websockets: https://websockets.readthedocs.io
45 |
--------------------------------------------------------------------------------
/supvisors/test/etc/supervisord_mc.conf:
--------------------------------------------------------------------------------
1 | [unix_http_server]
2 | file=/tmp/supervisor.sock
3 |
4 | [inet_http_server]
5 | port=:60000
6 | ;username=cliche
7 | ;password=p@$$w0rd
8 |
9 | [supervisord]
10 | logfile=./log/supervisord.log
11 | loglevel=info
12 | pidfile=/tmp/supervisord.pid
13 | minfds=1536
14 |
15 | [rpcinterface:supervisor]
16 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
17 |
18 | [supervisorctl]
19 | serverurl=http://localhost:60000
20 |
21 | [include]
22 | files = common/*/*.ini %(host_node_name)s/*.ini %(host_node_name)s/*/*.ini
23 |
24 | [rpcinterface:supvisors]
25 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
26 | multicast_group = 239.0.0.1:60001
27 | multicast_ttl = 1
28 | rules_files = etc/my_movies*.xml
29 | auto_fence = false
30 | event_link = WS
31 | event_port = 60002
32 | synchro_options = LIST,CORE,TIMEOUT,USER
33 | synchro_timeout = 20
34 | inactivity_ticks = 3
35 | disabilities_file = /tmp/disabilities.json
36 | starting_strategy = CONFIG
37 | conciliation_strategy = USER
38 | stats_enabled = true
39 | stats_collecting_period = 1
40 | stats_periods = 2.5,20,160
41 | stats_histo = 100
42 | stats_irix_mode = true
43 | tail_limit = 50MB
44 | tailf_limit = 50MB
45 | logfile = AUTO
46 |
47 | [ctlplugin:supvisors]
48 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
49 |
--------------------------------------------------------------------------------
/supvisors/client/clientutils.py:
--------------------------------------------------------------------------------
1 | # ======================================================================
2 | # Copyright 2023 Julien LE CLEACH
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ======================================================================
16 |
17 | from supervisor import loggers
18 | from supervisor.loggers import LevelsByName
19 |
20 |
21 | def create_logger(logfile=r'subscriber.log', loglevel=LevelsByName.INFO,
22 | fmt='%(asctime)s;%(levelname)s;%(message)s\n',
23 | rotating=True, maxbytes=10 * 1024 * 1024, backups=1, stdout=True):
24 | """ Return a simple Supervisor logger. """
25 | logger = loggers.getLogger(loglevel)
26 | if stdout:
27 | loggers.handle_stdout(logger, fmt)
28 | loggers.handle_file(logger, logfile, fmt, rotating, maxbytes, backups)
29 | return logger
30 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/template_etc/console/programs_console.ini:
--------------------------------------------------------------------------------
1 | [program:scen2_chart_view]
2 | command=./bin/scen2/chart_view.sh
3 | autostart=false
4 | killasgroup=true
5 | stopasgroup=true
6 | redirect_stderr=true
7 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
8 | stdout_logfile_backups=5
9 |
10 | [program:scen2_sensor_control]
11 | command=./bin/scen2/sensor_control.sh
12 | autostart=false
13 | killasgroup=true
14 | stopasgroup=true
15 | redirect_stderr=true
16 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
17 | stdout_logfile_backups=5
18 |
19 | [program:scen2_sensor_view]
20 | command=./bin/scen2/sensor_view.sh
21 | autostart=false
22 | killasgroup=true
23 | stopasgroup=true
24 | redirect_stderr=true
25 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
26 | stdout_logfile_backups=5
27 |
28 | [program:scen2_check_internal_data_bus]
29 | command=./bin/scen2/check_internal_data_bus.sh
30 | autostart=false
31 | startsecs=0
32 | killasgroup=true
33 | stopasgroup=true
34 | redirect_stderr=true
35 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
36 | stdout_logfile_backups=5
37 |
38 | [program:scen2_internal_data_bus]
39 | command=./bin/scen2/internal_data_bus.sh
40 | autostart=false
41 | startsecs=10
42 | killasgroup=true
43 | stopasgroup=true
44 | redirect_stderr=true
45 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
46 | stdout_logfile_backups=5
47 |
48 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_1/etc/rocky51/programs_rocky51.ini:
--------------------------------------------------------------------------------
1 | [program:scen1_hci]
2 | command=bin/scen1/hci.sh
3 | autostart=false
4 | killasgroup=true
5 | stopasgroup=true
6 | redirect_stderr=true
7 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
8 | stdout_logfile_backups=5
9 |
10 | [program:scen1_config_manager]
11 | command=bin/scen1/config_manager.sh
12 | autostart=false
13 | killasgroup=true
14 | stopasgroup=true
15 | redirect_stderr=true
16 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
17 | stdout_logfile_backups=5
18 |
19 | [program:scen1_data_processing]
20 | command=bin/scen1/data_processing.sh
21 | autostart=false
22 | killasgroup=true
23 | stopasgroup=true
24 | redirect_stderr=true
25 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
26 | stdout_logfile_backups=5
27 |
28 | [program:scen1_external_interface]
29 | command=bin/scen1/external_interface.sh
30 | autostart=false
31 | killasgroup=true
32 | stopasgroup=true
33 | redirect_stderr=true
34 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
35 | stdout_logfile_backups=5
36 |
37 | [program:scen1_data_recorder]
38 | command=bin/scen1/data_recorder.sh
39 | autostart=false
40 | killasgroup=true
41 | stopasgroup=true
42 | redirect_stderr=true
43 | stdout_logfile=log/%(program_name)s_%(ENV_CUR_DATE)s_%(ENV_CUR_TIME)s.log
44 | stdout_logfile_backups=5
45 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/console/programs_console.ini:
--------------------------------------------------------------------------------
1 | [program:scen2_chart_view]
2 | command = ./bin/scen2/chart_view.sh
3 | autostart = false
4 | killasgroup = true
5 | stopasgroup = true
6 | redirect_stderr = true
7 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
8 | stdout_logfile_backups = 5
9 |
10 | [program:scen2_sensor_control]
11 | command = ./bin/scen2/sensor_control.sh
12 | autostart = false
13 | killasgroup = true
14 | stopasgroup = true
15 | redirect_stderr = true
16 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
17 | stdout_logfile_backups = 5
18 |
19 | [program:scen2_sensor_view]
20 | command = ./bin/scen2/sensor_view.sh
21 | autostart = false
22 | killasgroup = true
23 | stopasgroup = true
24 | redirect_stderr = true
25 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
26 | stdout_logfile_backups = 5
27 |
28 | [program:scen2_check_internal_data_bus]
29 | command = ./bin/scen2/check_internal_data_bus.sh
30 | autostart = false
31 | startsecs = 0
32 | killasgroup = true
33 | stopasgroup = true
34 | redirect_stderr = true
35 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
36 | stdout_logfile_backups = 5
37 |
38 | [program:scen2_internal_data_bus]
39 | command = ./bin/scen2/internal_data_bus.sh
40 | autostart = false
41 | startsecs = 10
42 | killasgroup = true
43 | stopasgroup = true
44 | redirect_stderr = true
45 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
46 | stdout_logfile_backups = 5
47 |
48 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/LoggerLevels.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 |
20 | /**
21 | * The LoggerLevels enumeration.
22 | */
23 | public enum LoggerLevels {
24 | BLATHER(3),
25 | TRACE(5),
26 | DEBUG(10),
27 | INFO(20),
28 | WARN(30),
29 | ERROR(40),
30 | CRITICAL(50);
31 |
32 | /** The level code. */
33 | private int levelCode;
34 |
35 | /** The constructor links the state code to the state name. */
36 | private LoggerLevels(final int levelCode) {
37 | this.levelCode = levelCode;
38 | }
39 |
40 | /**
41 | * The getLevelCode method returns the value of the logger level.
42 | *
43 | * @return String: The value of the logger level.
44 | */
45 | public int getLevelCode() {
46 | return this.levelCode;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/supvisors/ui/css/card.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Supvisors common style for a card box
19 | */
20 |
21 | div.card {
22 | padding: 0 15px;
23 | align-items: center;
24 | border: 1px solid black outset;
25 | border-radius: 6px;
26 | box-shadow: 0px 2px 10px black;
27 | background-image: linear-gradient(180deg, var(--dark1-color), var(--light2-color), var(--dark1-color));
28 | }
29 |
30 | div.card table.status {
31 | border: none;
32 | background: transparent;
33 | }
34 |
35 | div.card table.status th, div.card table.status td {
36 | border: none;
37 | background: transparent;
38 | }
39 |
40 | div.card table.status td {
41 | text-align: center;
42 | }
43 |
44 | div.card table.status .table_main {
45 | font-size: 1em;
46 | text-align: center;
47 | }
48 |
49 | div.card table.status .table_title {
50 | text-align: right;
51 | }
52 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Supvisors documentation build configuration file
4 |
5 | import os
6 | import sys
7 | from datetime import date
8 |
9 | # -- General configuration ------------------------------------------------
10 |
11 | # Sphinx extension module names
12 | extensions = ['sphinx.ext.autodoc', 'myst_parser']
13 |
14 | # Add any paths that contain templates here, relative to this directory.
15 | templates_path = []
16 |
17 | # The suffix(es) of source filenames.
18 | source_suffix = ['.rst', '.md']
19 |
20 | # The master toctree document.
21 | master_doc = 'index'
22 |
23 | # General information about the project.
24 | year = date.today().year
25 |
26 | project = u'Supvisors'
27 | copyright = u'2016-{}, Julien Le Cléach'.format(year)
28 | author = u'Julien Le Cléach'
29 |
30 | # The version info for the project you're documenting, acts as replacement for
31 | # |version| and |release|, also used in various other places throughout the
32 | # built documents.
33 | #
34 | # The Supvisors version.
35 | parent = os.path.dirname(os.path.dirname(__file__))
36 | sys.path.append(os.path.abspath(parent))
37 | version_txt = os.path.join(parent, 'supvisors/version.txt')
38 | version = release = open(version_txt).read().split('=')[1].strip()
39 |
40 | exclude_patterns = ['.build', 'Thumbs.db', '.DS_Store']
41 |
42 | pygments_style = 'sphinx'
43 |
44 | # -- Options for HTML output ----------------------------------------------
45 |
46 | # html_theme = 'sphinx_rtd_theme'
47 | html_theme = 'renku'
48 |
49 | html_static_path = []
50 |
--------------------------------------------------------------------------------
/supvisors/ui/css/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Supvisors Application page style
19 | */
20 |
21 | /* Style for application operational status */
22 | .status_empty, .status_green, .status_yellow, .status_red {
23 | padding: 15px 50px;
24 | }
25 |
26 | .status_empty {
27 | background: url(../img/leds_empty_30.png) no-repeat center;
28 | }
29 |
30 | .status_green {
31 | background: url(../img/leds_green_30.png) no-repeat center;
32 | }
33 |
34 | .status_yellow {
35 | background: url(../img/leds_yellow_30.png) no-repeat center;
36 | }
37 |
38 | .status_red {
39 | background: url(../img/leds_red_30.png) no-repeat center;
40 | }
41 |
42 | /* update the background of the strategies box */
43 | #strategies {
44 | background-image: linear-gradient(180deg, var(--light2-color), var(--light1-color));
45 | }
46 |
47 | #strategies div.button_group {
48 | background-image: none;
49 | }
50 |
51 | #strategies div.button_group:nth-child(2) {
52 | padding-top: 0;
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/supvisors/test/etc/supervisord.conf:
--------------------------------------------------------------------------------
1 | [unix_http_server]
2 | file=/tmp/supervisor.sock
3 |
4 | [inet_http_server]
5 | port=:60000
6 | ;username=cliche
7 | ;password=p@$$w0rd
8 |
9 | [supervisord]
10 | logfile=./log/supervisord.log
11 | loglevel=info
12 | pidfile=/tmp/supervisord.pid
13 |
14 | [rpcinterface:supervisor]
15 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
16 |
17 | [supervisorctl]
18 | serverurl=http://localhost:60000
19 |
20 | [include]
21 | files = common/*/*.ini
22 | %(host_node_name)s/*.ini
23 | %(host_node_name)s/*/*.ini
24 |
25 | [rpcinterface:supvisors]
26 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
27 | software_name = Supvisors Tests
28 | software_icon = ../ui/img/icon.png
29 | supvisors_list = 17.0.1.11,supv02,192.168.1.70:30000
30 | rules_files = etc/my_movies*.xml
31 | css_files = ui/test.css
32 | auto_fence = false
33 | event_link = ZMQ
34 | event_port = 60002
35 | synchro_options = LIST,CORE,TIMEOUT,USER
36 | synchro_timeout = 30
37 | inactivity_ticks = 3
38 | core_identifiers = supv-01,supv-03
39 | disabilities_file = /tmp/disabilities.json
40 | starting_strategy = CONFIG
41 | conciliation_strategy = USER
42 | stats_enabled = true
43 | stats_collecting_period = 1
44 | stats_periods = 2.5,20,160
45 | stats_histo = 100
46 | stats_irix_mode = true
47 | tail_limit = 50MB
48 | tailf_limit = 50MB
49 | logfile = AUTO
50 | ;logfile = ./log/supvisors.log
51 | ;logfile_maxbytes = 50MB
52 | ;logfile_backups = 10
53 | ;loglevel = debug
54 |
55 | [ctlplugin:supvisors]
56 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
57 |
--------------------------------------------------------------------------------
/supvisors/tools/apis/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | # ======================================================================
5 | # Copyright 2022 Julien LE CLEACH
6 | #
7 | # Licensed under the Apache License, Version 2.0 (the "License");
8 | # you may not use this file except in compliance with the License.
9 | # You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing, software
14 | # distributed under the License is distributed on an "AS IS" BASIS,
15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | # See the License for the specific language governing permissions and
17 | # limitations under the License.
18 | # ======================================================================
19 |
20 | from flask_restx import Api
21 | from supervisor.compat import xmlrpclib
22 |
23 | from .system_namespace import api as system_api
24 | from .supervisor_namespace import api as supervisor_api
25 | from .supvisors_namespace import api as supvisors_api
26 |
27 | # create Api with all namespaces
28 | api = Api(title='Supvisors Flask interface')
29 | api.add_namespace(system_api)
30 | api.add_namespace(supervisor_api)
31 | api.add_namespace(supvisors_api)
32 |
33 |
34 | @api.errorhandler
35 | def default_error_handler(error):
36 | """ Default error handler. """
37 | return {'message': str(error)}, getattr(error, 'code', 500)
38 |
39 |
40 | @api.errorhandler(xmlrpclib.Fault)
41 | def supervisor_error_handler(error):
42 | """ Supervisor error handler. """
43 | return {'message': error.faultString, 'code': error.faultCode}, 400
44 |
45 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/gathering/configure.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # get consoles from Supvisors rules file
4 | RULES_FILE=etc/supvisors_rules.xml
5 |
6 | PY_ALIAS="from xml.etree.ElementTree import parse
7 | root = parse('$RULES_FILE').getroot()
8 | consoles = root.findtext('./alias[@name=\"consoles\"]')
9 | print(consoles.replace(',', ' '))
10 | "
11 |
12 | CONSOLES=`python3 -c "$PY_ALIAS"`
13 | NB_CONSOLES=`echo $CONSOLES | wc -w`
14 |
15 | # clear bin folder
16 | rm -f bin/*
17 |
18 | # link bin folders
19 | for scenario in `ls -d ../scen*`
20 | do
21 | bin_path=`ls -d $scenario/bin/*`
22 | bin_dir=`basename $bin_path`
23 | ln -s ../$scenario/bin/$bin_dir bin/$bin_dir
24 | done
25 |
26 | # clear configuration files
27 | find etc -name "*.ini" | xargs rm -f
28 |
29 | # copy Scenario 1 configuration
30 | mkdir -p etc/scenario_1
31 | for folder in `ls -d ../scenario_1/etc/*/`
32 | do
33 | cp -rf $folder etc/scenario_1
34 | done
35 |
36 | # duplicate Scenario 2 SRV+HCI applications 3 times
37 | supvisors_breed -d etc/scenario_2 -t ../scenario_2/template_etc -b scen2_srv=3 scen2_hci=3 -x -v
38 |
39 | # duplicate Scenario 3 HCI applications iaw the number of consoles
40 | # option -x is used to separate the definitions
41 | supvisors_breed -d etc/scenario_3 -t ../scenario_3/template_etc -b scen3_hci=$NB_CONSOLES -x -v
42 |
43 | # copy Scenario 3 common + server configurations
44 | cp -rf ../scenario_3/etc/common etc/scenario_3
45 | cp -rf ../scenario_3/etc/server etc/scenario_3
46 |
47 | # assign one HCI application per console
48 | for console in $CONSOLES
49 | do
50 | mkdir -p etc/scenario_3/console/$console
51 | FIRST=`ls etc/scenario_3/console/group_scen3*.ini | head -1`
52 | mv -f $FIRST etc/scenario_3/console/$console
53 | done
54 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/server/group_server.ini:
--------------------------------------------------------------------------------
1 | [group:scen3_srv]
2 | programs=scen3_item_manager,scen3_track_manager,scen3_system_health,scen3_common_bus_interface,scen3_check_common_data_bus,scen3_check_internal_data_bus
3 |
4 | [program:scen3_item_manager]
5 | command=./bin/scen3/item_manager.sh
6 | autostart=false
7 | killasgroup=true
8 | stopasgroup=true
9 | redirect_stderr=true
10 | stdout_logfile=log/%(program_name)s.log
11 | stdout_logfile_backups=5
12 |
13 | [program:scen3_track_manager]
14 | command=./bin/scen3/track_manager.sh
15 | autostart=false
16 | killasgroup=true
17 | stopasgroup=true
18 | redirect_stderr=true
19 | stdout_logfile=log/%(program_name)s.log
20 | stdout_logfile_backups=5
21 |
22 | [program:scen3_system_health]
23 | command=./bin/scen3/system_health.sh
24 | autostart=false
25 | killasgroup=true
26 | stopasgroup=true
27 | redirect_stderr=true
28 | stdout_logfile=log/%(program_name)s.log
29 | stdout_logfile_backups=5
30 |
31 | [program:scen3_check_common_data_bus]
32 | command=./bin/scen3/check_common_data_bus.sh
33 | autostart=false
34 | startsecs=0
35 | killasgroup=true
36 | stopasgroup=true
37 | redirect_stderr=true
38 | stdout_logfile=log/%(program_name)s.log
39 | stdout_logfile_backups=5
40 |
41 | [program:scen3_common_bus_interface]
42 | command=./bin/scen3/common_bus_interface.sh
43 | autostart=false
44 | killasgroup=true
45 | stopasgroup=true
46 | redirect_stderr=true
47 | stdout_logfile=log/%(program_name)s.log
48 | stdout_logfile_backups=5
49 |
50 | [program:scen3_check_internal_data_bus]
51 | command=./bin/scen3/check_internal_data_bus.sh
52 | autostart=false
53 | startsecs=0
54 | killasgroup=true
55 | stopasgroup=true
56 | redirect_stderr=true
57 | stdout_logfile=log/%(program_name)s.log
58 | stdout_logfile_backups=5
59 |
60 |
--------------------------------------------------------------------------------
/supvisors/ui/css/index.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Supvisors Main page
19 | */
20 |
21 | /* Contents part */
22 | #index_contents {
23 | display: flex;
24 | flex: 1;
25 | justify-content: space-evenly;
26 | flex-wrap: wrap;
27 | gap: 13px;
28 | overflow: auto;
29 | padding: 10px;
30 | }
31 |
32 | #index_contents .card {
33 | display: flex;
34 | margin: auto;
35 | }
36 |
37 | #index_contents table {
38 | height: 100%;
39 | margin: 10px;
40 | }
41 |
42 | #index_contents th:not(.state_cell) {
43 | height: 18px;
44 | background-image: linear-gradient(180deg, var(--dark2-color), var(--dark1-color));
45 | }
46 |
47 | #index_contents th a.active {
48 | color: var(--selected-color);
49 | }
50 |
51 | #index_contents tr:first-child th {
52 | border-bottom: solid 1px var(--border-color);
53 | }
54 |
55 | #index_contents td:nth-child(1) {
56 | vertical-align: center;
57 | }
58 |
59 | #index_contents td.process_list {
60 | max-width: 250px;
61 | }
62 |
63 | #index_contents tbody .button {
64 | margin-bottom: 4px;
65 | }
66 |
67 | /* fix state columns width */
68 | #index_contents .state_cell {
69 | width: 50px;
70 | }
71 |
--------------------------------------------------------------------------------
/supvisors/tools/supvisorsflask.py:
--------------------------------------------------------------------------------
1 | # ======================================================================
2 | # Copyright 2022 Julien LE CLEACH
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ======================================================================
16 |
17 | import sys
18 |
19 | from flask import Flask, g
20 | from supervisor.childutils import getRPCInterface
21 |
22 | from .apis import api
23 | from .apis.utils import parse_args
24 |
25 | # Create the Flask application
26 | app = Flask(__name__)
27 | api.init_app(app)
28 |
29 |
30 | @app.before_request
31 | def get_supervisor_proxy():
32 | """ Get Supervisor proxy before any request. """
33 | # get the Supervisor proxy
34 | supervisor_url = app.config.get('url')
35 | g.proxy = getRPCInterface({'SUPERVISOR_SERVER_URL': supervisor_url})
36 | # provide version information
37 | api.version = g.proxy.supvisors.get_api_version()
38 |
39 |
40 | def main():
41 | # read the arguments
42 | args = parse_args(sys.argv[1:])
43 | if args.debug:
44 | print(f'ArgumentParser: {args}')
45 | # start the Flask application
46 | app.config['url'] = args.supervisor_url
47 | flask_options = {k: v for k, v in vars(args).items()
48 | if k in ['host', 'port', 'debug'] and v is not None}
49 | app.run(**flask_options)
50 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/SupvisorsInstanceState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 | /**
20 | * The SupvisorsInstanceState enumeration.
21 | *
22 | * STOPPED: used when the local Supvisors instance does not receive any heartbeat message from the remote Supvisors instance (default state).
23 | * CHECKING: used when the local Supvisors instance is checking the status of the remote Supvisors instance.
24 | * CHECKED: used when the local Supvisors instance has checked the status of the remote Supvisors instance.
25 | * RUNNING: used when the local Supvisors instance is ready to work with the remote Supvisors instance.
26 | * FAILED: used when the local Supvisors instance fails to communicate with the remote Supvisors instance.
27 | * ISOLATED: used when the local Supvisors instance has actually disconnected the remote Supvisors instance.
28 | */
29 | public enum SupvisorsInstanceState {
30 | STOPPED(0),
31 | CHECKING(1),
32 | CHECKED(2),
33 | RUNNING(3),
34 | FAILED(4),
35 | ISOLATED(5);
36 |
37 | /** The state code. */
38 | private final int state;
39 |
40 | /** The constructor links the state code to the state name. */
41 | private SupvisorsInstanceState(int state) {
42 | this.state = state;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/template_etc/server/programs_server.ini:
--------------------------------------------------------------------------------
1 | [program:scen2_config_manager]
2 | command=./bin/scen2/config_manager.sh
3 | autostart=false
4 | killasgroup=true
5 | stopasgroup=true
6 | redirect_stderr=true
7 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
8 | stdout_logfile_backups=5
9 |
10 | [program:scen2_check_common_data_bus]
11 | command=./bin/scen2/check_common_data_bus.sh
12 | autostart=false
13 | startsecs=0
14 | killasgroup=true
15 | stopasgroup=true
16 | redirect_stderr=true
17 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
18 | stdout_logfile_backups=5
19 |
20 | [program:scen2_common_bus_interface]
21 | command=./bin/scen2/common_bus_interface.sh
22 | autostart=false
23 | killasgroup=true
24 | stopasgroup=true
25 | redirect_stderr=true
26 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
27 | stdout_logfile_backups=5
28 |
29 | [program:scen2_check_internal_data_bus]
30 | command=./bin/scen2/check_internal_data_bus.sh
31 | autostart=false
32 | startsecs=0
33 | killasgroup=true
34 | stopasgroup=true
35 | redirect_stderr=true
36 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
37 | stdout_logfile_backups=5
38 |
39 | [program:scen2_internal_data_bus]
40 | command=./bin/scen2/internal_data_bus.sh
41 | autostart=false
42 | startsecs=10
43 | killasgroup=true
44 | stopasgroup=true
45 | redirect_stderr=true
46 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
47 | stdout_logfile_backups=5
48 |
49 | [program:scen2_data_processing]
50 | command=./bin/scen2/data_processing.sh
51 | autostart=false
52 | killasgroup=true
53 | stopasgroup=true
54 | redirect_stderr=true
55 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
56 | stdout_logfile_backups=5
57 |
58 | [program:scen2_sensor_acquisition]
59 | command=./bin/scen2/sensor_acquisition.sh
60 | autostart=false
61 | killasgroup=true
62 | stopasgroup=true
63 | redirect_stderr=true
64 | stdout_logfile=log/%(group_name)s_%(program_name)s.log
65 | stdout_logfile_backups=5
66 |
67 |
--------------------------------------------------------------------------------
/supvisors/tests/test_clientutils.py:
--------------------------------------------------------------------------------
1 | # ======================================================================
2 | # Copyright 2022 Julien LE CLEACH
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ======================================================================
16 |
17 |
18 | from unittest.mock import call
19 |
20 | from supervisor.loggers import Logger, LevelsByName
21 |
22 | from supvisors.client.clientutils import create_logger
23 |
24 |
25 | def test_create_logger(mocker):
26 | """ Test the create_logger method. """
27 | mocked_stdout = mocker.patch('supervisor.loggers.handle_stdout')
28 | mocked_file = mocker.patch('supervisor.loggers.handle_file')
29 | # test default
30 | default_format = '%(asctime)s;%(levelname)s;%(message)s\n'
31 | logger = create_logger()
32 | assert isinstance(logger, Logger)
33 | assert logger.level == LevelsByName.INFO
34 | assert mocked_stdout.call_args_list == [call(logger, default_format)]
35 | assert mocked_file.call_args_list == [call(logger, r'subscriber.log', default_format, True, 10485760, 1)]
36 | mocker.resetall()
37 | # test with parameters
38 | new_format = '%(asctime)s %(message)s'
39 | logger = create_logger('/tmp/client.log', LevelsByName.CRIT, new_format, False, 1024, 10, False)
40 | assert isinstance(logger, Logger)
41 | assert logger.level == LevelsByName.CRIT
42 | assert not mocked_stdout.called
43 | assert mocked_file.call_args_list == [call(logger, '/tmp/client.log', new_format, False, 1024, 10)]
44 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Run all tests
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | tests:
7 | runs-on: ubuntu-latest
8 | strategy:
9 | fail-fast: false
10 | matrix:
11 | python-version: [3.9, "3.10", 3.11, 3.12, 3.13]
12 |
13 | steps:
14 | - uses: actions/checkout@v3
15 |
16 | - name: Set up Python ${{ matrix.python-version }}
17 | uses: actions/setup-python@v4
18 | with:
19 | python-version: ${{ matrix.python-version }}
20 |
21 | - name: Show Python version
22 | run: python -V
23 |
24 | - name: Set TOXENV based on Python version
25 | run: python -c "import sys; print(f'TOXENV=py{sys.version_info.major}{sys.version_info.minor}')" | tee -a $GITHUB_ENV
26 |
27 | - name: Install dependencies
28 | run: pip install virtualenv tox
29 |
30 | - name: Run the unit tests
31 | run: tox
32 |
33 | coverage:
34 | runs-on: ubuntu-latest
35 | strategy:
36 | fail-fast: false
37 |
38 | steps:
39 | - uses: actions/checkout@v3
40 |
41 | - name: Set up Python ${{ matrix.python-version }}
42 | uses: actions/setup-python@v4
43 | with:
44 | python-version: '3.11'
45 |
46 | - name: Install dependencies
47 | run: pip install virtualenv tox
48 |
49 | - name: Run unit test coverage
50 | run: TOXENV=cover tox
51 |
52 | - name: Coveralls
53 | # does not work yet as pytest-cov does not provide Lcov files
54 | # uses: coverallsapp/github-action@master
55 | run: pip install coveralls && coveralls --service=github
56 | env:
57 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58 |
59 | docs:
60 | runs-on: ubuntu-latest
61 |
62 | steps:
63 | - uses: actions/checkout@v3
64 |
65 | - name: Set up Python ${{ matrix.python-version }}
66 | uses: actions/setup-python@v4
67 | with:
68 | python-version: '3.11'
69 |
70 | - name: Install dependencies
71 | run: pip install virtualenv tox
72 |
73 | - name: Build the docs
74 | run: TOXENV=docs tox
75 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/server/programs_server.ini:
--------------------------------------------------------------------------------
1 | [program:scen2_config_manager]
2 | command = ./bin/scen2/config_manager.sh
3 | autostart = false
4 | killasgroup = true
5 | stopasgroup = true
6 | redirect_stderr = true
7 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
8 | stdout_logfile_backups = 5
9 |
10 | [program:scen2_check_common_data_bus]
11 | command = ./bin/scen2/check_common_data_bus.sh
12 | autostart = false
13 | startsecs = 0
14 | killasgroup = true
15 | stopasgroup = true
16 | redirect_stderr = true
17 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
18 | stdout_logfile_backups = 5
19 |
20 | [program:scen2_common_bus_interface]
21 | command = ./bin/scen2/common_bus_interface.sh
22 | autostart = false
23 | killasgroup = true
24 | stopasgroup = true
25 | redirect_stderr = true
26 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
27 | stdout_logfile_backups = 5
28 |
29 | [program:scen2_check_internal_data_bus]
30 | command = ./bin/scen2/check_internal_data_bus.sh
31 | autostart = false
32 | startsecs = 0
33 | killasgroup = true
34 | stopasgroup = true
35 | redirect_stderr = true
36 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
37 | stdout_logfile_backups = 5
38 |
39 | [program:scen2_internal_data_bus]
40 | command = ./bin/scen2/internal_data_bus.sh
41 | autostart = false
42 | startsecs = 10
43 | killasgroup = true
44 | stopasgroup = true
45 | redirect_stderr = true
46 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
47 | stdout_logfile_backups = 5
48 |
49 | [program:scen2_data_processing]
50 | command = ./bin/scen2/data_processing.sh
51 | autostart = false
52 | killasgroup = true
53 | stopasgroup = true
54 | redirect_stderr = true
55 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
56 | stdout_logfile_backups = 5
57 |
58 | [program:scen2_sensor_acquisition]
59 | command = ./bin/scen2/sensor_acquisition.sh
60 | autostart = false
61 | killasgroup = true
62 | stopasgroup = true
63 | redirect_stderr = true
64 | stdout_logfile = log/%(group_name)s_%(program_name)s.log
65 | stdout_logfile_backups = 5
66 |
67 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/SupvisorsState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 | /**
20 | * The State enumeration for Supvisors.
21 | *
22 | * OFF is the Supvisors entry state, used until the local Supvisors instance is operational.
23 | * SYNCHRONIZATION is used when Supvisors is synchronizing all Supvisors instances.
24 | * ELECTION is used when Supvisors is electing the Supvisors Master instance (must be unanimous).
25 | * DISTRIBUTION is used when Supvisors is starting applications automatically.
26 | * OPERATION is used when Supvisors is working normally.
27 | * CONCILIATION is used when Supvisors is conciliating conflicts due to multiple instance of the same process.
28 | * RESTARTING is used when Supvisors is stopping all processes before restarting all Supvisors instances.
29 | * SHUTTING_DOWN is used when Supvisors is stopping all processes before shutting down all Supvisors instances.
30 | * FINAL is used just before Supvisors is shut down.
31 | */
32 | public enum SupvisorsState {
33 | OFF(0),
34 | SYNCHRONIZATION(1),
35 | ELECTION(2),
36 | DISTRIBUTION(3),
37 | OPERATION(4),
38 | CONCILIATION(5),
39 | RESTARTING(6),
40 | SHUTTING_DOWN(7),
41 | FINAL(8);
42 |
43 | /** The state code. */
44 | private int stateCode;
45 |
46 | /** The constructor links the state code to the state name. */
47 | private SupvisorsState(final int stateCode) {
48 | this.stateCode = stateCode;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/supvisors/test/test_supervisor_177/etc/supervisord.conf:
--------------------------------------------------------------------------------
1 | [inet_http_server]
2 | port=:60000
3 |
4 | [supervisord]
5 | logfile=log/supervisord.log
6 | logfile_backups=10
7 | loglevel=info
8 | pidfile=/tmp/supervisord.pid
9 | nodaemon=false
10 | umask=002
11 |
12 | [rpcinterface:supervisor]
13 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
14 |
15 | [rpcinterface:supvisors]
16 | supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
17 |
18 | [supervisorctl]
19 | serverurl=http://localhost:60000
20 |
21 | [ctlplugin:supvisors]
22 | supervisor.ctl_factory = supvisors.supvisorsctl:make_supvisors_controller_plugin
23 |
24 |
25 | # Configuration to test Supervisor issue #177
26 | [group:dummy1]
27 | programs=autostarted,stopped
28 |
29 | [group:dummy2]
30 | programs=autostarted,control
31 |
32 | [program:control]
33 | command=zenity --info --text=%(program_name)s
34 | autostart=true
35 | killasgroup=true
36 | stopasgroup=true
37 | redirect_stderr=true
38 | stdout_logfile=log/%(program_name)s.log
39 |
40 | [program:autostarted]
41 | command=zenity --info --text=%(group_name)s-%(program_name)s_%(process_num)d
42 | process_name=%(program_name)s_%(process_num)d
43 | numprocs=2
44 | numprocs_start=10
45 | autostart=true
46 | killasgroup=true
47 | stopasgroup=true
48 | redirect_stderr=true
49 | stdout_logfile=log/%(group_name)s-%(program_name)s_%(process_num)d.log
50 |
51 | [program:stopped]
52 | command=zenity --text=%(group_name)s-%(program_name)s
53 | process_name=%(program_name)s_%(process_num)d
54 | numprocs=2
55 | numprocs_start=20
56 | autostart=false
57 | killasgroup=true
58 | stopasgroup=true
59 | redirect_stderr=true
60 | stdout_logfile=log/%(program_name)s_%(process_num)d.log
61 |
62 | [eventlistener:listener]
63 | command=python bin/evt_listener.py
64 | events=EVENT
65 | buffer_size=50
66 | autostart=true
67 | stderr_logfile=log/%(program_name)s.log
68 |
69 | [eventlistener:multiple_listener]
70 | command=python bin/evt_listener.py
71 | process_name=%(program_name)s_%(process_num)02d
72 | numprocs=2
73 | events=PROCESS_STATE
74 | buffer_size=50
75 | autostart=true
76 | stderr_logfile=log/%(program_name)s_%(process_num)d.log
77 |
--------------------------------------------------------------------------------
/supvisors/tools/apis/system_namespace.py:
--------------------------------------------------------------------------------
1 | # ======================================================================
2 | # Copyright 2022 Julien LE CLEACH
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ======================================================================
16 |
17 | from flask import g, jsonify
18 | from flask_restx import Namespace, Resource
19 | from supervisor.xmlrpc import SystemNamespaceRPCInterface
20 |
21 | from .utils import get_docstring_description, get_docstring_parameters
22 |
23 | # Supervisor System part
24 | api = Namespace('system', description='System operations')
25 |
26 |
27 | @api.route('/listMethods', methods=('GET',))
28 | @api.doc(description=get_docstring_description(SystemNamespaceRPCInterface.listMethods))
29 | class SystemListMethods(Resource):
30 | @staticmethod
31 | def get():
32 | return jsonify(g.proxy.system.listMethods())
33 |
34 |
35 | @api.route('/methodHelp/', methods=('GET',))
36 | @api.doc(description=get_docstring_description(SystemNamespaceRPCInterface.methodHelp))
37 | class SystemMethodHelp(Resource):
38 | @api.doc(params=get_docstring_parameters(SystemNamespaceRPCInterface.methodHelp))
39 | def get(self, name):
40 | return g.proxy.system.methodHelp(name)
41 |
42 |
43 | @api.route('/methodSignature/', methods=('GET',))
44 | @api.doc(description=get_docstring_description(SystemNamespaceRPCInterface.methodSignature))
45 | class SystemMethodSignature(Resource):
46 | @api.doc(params=get_docstring_parameters(SystemNamespaceRPCInterface.methodSignature))
47 | def get(self, name):
48 | return jsonify(g.proxy.system.methodSignature(name))
49 |
--------------------------------------------------------------------------------
/supvisors/web/viewmaintail.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | # ======================================================================
5 | # Copyright 2022 Julien LE CLEACH
6 | #
7 | # Licensed under the Apache License, Version 2.0 (the "License");
8 | # you may not use this file except in compliance with the License.
9 | # You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing, software
14 | # distributed under the License is distributed on an "AS IS" BASIS,
15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | # See the License for the specific language governing permissions and
17 | # limitations under the License.
18 | # ======================================================================
19 |
20 | from urllib.parse import quote
21 |
22 | from supervisor.compat import as_string
23 | from supervisor.web import MeldView
24 | from supervisor.xmlrpc import Faults, RPCError
25 |
26 |
27 | class MainTailView(MeldView):
28 | """ Adaptation of supervisor.web.TailView to display the logs of Supervisor. """
29 |
30 | def render(self):
31 | """ Rendering of the Main tail page. """
32 | supvisors = self.context.supervisord.supvisors
33 | form = self.context.form
34 | # get log limit to read
35 | limit = form.get('limit', '1024')
36 | limit = min(-1024, int(limit) * -1 if limit.isdigit() else -1024)
37 | # read Supervisor logs from RPC interface
38 | rpc_intf = supvisors.supervisor_data.supervisor_rpc_interface
39 | try:
40 | tail = rpc_intf.readLog(limit, 0)
41 | except RPCError as e:
42 | if e.code == Faults.NO_FILE:
43 | tail = 'No file for Supervisor'
44 | else:
45 | tail = f'ERROR: unexpected rpc fault [{e.code}] {e.text}'
46 | # generate page
47 | root = self.clone()
48 | root.findmeld('title').content('Supervisor tail')
49 | root.findmeld('tailbody').content(tail)
50 | url = f'maintail.html?limit={quote(str(abs(limit)))}'
51 | root.findmeld('refresh_anchor').attributes(href=url)
52 | return as_string(root.write_xhtmlstring())
53 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/supvisors_rules_mc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | @SERVER
6 | 2
7 | true
8 | 2
9 |
10 |
11 | @SERVER
12 | 1
13 | true
14 | true
15 |
16 |
17 |
18 |
19 |
20 | 1
21 | LESS_LOADED
22 | CONTINUE
23 | RESTART_PROCESS
24 |
25 |
26 | model_services
27 | 3
28 |
29 |
30 | check_data_bus
31 | 2
32 |
33 |
34 | model_services
35 |
36 |
37 | check_data_bus
38 |
39 |
40 |
41 |
42 |
43 |
44 | SINGLE_INSTANCE
45 | #,@CONSOLE
46 | 3
47 | CONTINUE
48 |
49 |
50 | 2
51 | 8
52 |
53 |
54 | check_data_bus
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/ProcessState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 | import com.google.gson.annotations.SerializedName;
20 | import java.util.HashMap;
21 |
22 | /**
23 | * The ProcessState enumeration.
24 | *
25 | * See the description in the Supervisor documentation.
26 | * http://supervisord.org/subprocess.html#process-states
27 | *
28 | * The DELETED enumeration has been added to support the Supervisor issue #177 in the event where the user decreases
29 | * dynamically the numprocs value and thus processes are removed from Supervisor.
30 | */
31 | public enum ProcessState {
32 | @SerializedName("0")
33 | STOPPED(0),
34 | @SerializedName("10")
35 | STARTING(10),
36 | @SerializedName("20")
37 | RUNNING(20),
38 | @SerializedName("30")
39 | BACKOFF(30),
40 | @SerializedName("40")
41 | STOPPING(40),
42 | @SerializedName("100")
43 | EXITED(100),
44 | @SerializedName("200")
45 | FATAL(200),
46 | @SerializedName("1000")
47 | UNKNOWN(1000),
48 | @SerializedName("-1")
49 | DELETED(-1);
50 |
51 | /** The state code. */
52 | private int stateCode;
53 |
54 | /** Keep a map to get enum from int. */
55 | private static HashMap map =
56 | new HashMap();
57 |
58 | static {
59 | for (ProcessState state : ProcessState.values()) {
60 | map.put(state.stateCode, state);
61 | }
62 | }
63 |
64 | /** The constructor links the state code to the state name. */
65 | private ProcessState(final int stateCode) {
66 | this.stateCode = stateCode;
67 | }
68 |
69 | /** Get a ProcessState enum from integer. */
70 | public static ProcessState valueOf(int stateCode) {
71 | return map.get(stateCode);
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/SupervisorFaults.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 | import java.util.HashMap;
20 |
21 |
22 | /**
23 | * The SupervisorFaults enumeration.
24 | *
25 | * These are the faults defined in the supervisor.xmlprc module
26 | */
27 | public enum SupervisorFaults {
28 | UNKNOWN_METHOD(1),
29 | INCORRECT_PARAMETERS(2),
30 | BAD_ARGUMENTS(3),
31 | SIGNATURE_UNSUPPORTED(4),
32 | SHUTDOWN_STATE(6),
33 | BAD_NAME(10),
34 | BAD_SIGNAL(11),
35 | NO_FILE(20),
36 | NOT_EXECUTABLE(21),
37 | FAILED(30),
38 | ABNORMAL_TERMINATION(40),
39 | SPAWN_ERROR(50),
40 | ALREADY_STARTED(60),
41 | NOT_RUNNING(70),
42 | SUCCESS(80),
43 | ALREADY_ADDED(90),
44 | STILL_RUNNING(91),
45 | CANT_REREAD(92);
46 |
47 | /** The fault code. */
48 | private int faultCode;
49 |
50 | /** The mapping between fault codes and enumeration values. */
51 | private static HashMap mapping = new HashMap();
52 |
53 | /** Initialization of the static map. */
54 | static {
55 | for (SupervisorFaults fault : SupervisorFaults.values()) {
56 | mapping.put(fault.faultCode, fault);
57 | }
58 | }
59 |
60 | /** The constructor links the fault code to the fault name. */
61 | private SupervisorFaults(final int faultCode) {
62 | this.faultCode = faultCode;
63 | }
64 |
65 | /**
66 | * The getFault function returns the enumeration value associated to the fault code.
67 | *
68 | * @param int faultCode: The fault code.
69 | * @return SupervisorFaults: the corresponding enumeration
70 | */
71 | public static SupervisorFaults getFault(final int faultCode) {
72 | return mapping.get(faultCode);
73 | }
74 |
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/supvisors/ui/css/message.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Supvisors style for Message / Time boxes
19 | */
20 |
21 | #statusBox {
22 | display: flex;
23 | flex-direction: row;
24 | justify-content: space-around;
25 | }
26 |
27 | #messageBox, #timeBox {
28 | min-height: 33px;
29 | max-height: 33px;
30 | }
31 |
32 | #messageBox {
33 | display: flex;
34 | align-items: center;
35 | font-size: 0.9em;
36 | width: 100%;
37 | margin: 5px;
38 | }
39 |
40 | #timeBox {
41 | display: flex;
42 | flex-direction: column;
43 | min-width: 200px;
44 | max-width: 200px;
45 | margin: 5px 5px 5px 0;
46 | text-align: right;
47 | }
48 |
49 | #timeBox p {
50 | font-size: 0.8em;
51 | }
52 |
53 | .empty, .info, .warn, .erro {
54 | padding: 5px;
55 | margin: 5px auto;
56 | border-radius: 10px;
57 | }
58 |
59 | .empty {
60 | background-image: linear-gradient(165deg, var(--navbg-color), silver);
61 | border: 1px grey inset;
62 | }
63 |
64 | .info {
65 | background-image: linear-gradient(165deg, var(--navbg-color), dodgerblue);
66 | border: 1px blue inset;
67 | }
68 |
69 | #messageBox.info::before {
70 | content: url(../img/info_20.png) '\00a0';
71 | float: left;
72 | position: relative;
73 | top: 2px;
74 | }
75 |
76 | .warn {
77 | background-image: linear-gradient(165deg, var(--navbg-color), #f90);
78 | border: 1px orange inset;
79 | }
80 |
81 | .warn::before {
82 | content: url(../img/warn_20.png) '\00a0';
83 | float: left;
84 | position: relative;
85 | top: 2px;
86 | }
87 |
88 | .erro {
89 | background-image: linear-gradient(165deg, var(--navbg-color), orangered);
90 | border: 1px red inset;
91 | }
92 |
93 | .erro::before {
94 | content: url(../img/erro_20.png) '\00a0';
95 | float: left;
96 | position: relative;
97 | top: 2px;
98 | }
99 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_3/etc/supvisors_rules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | server_1,server_2,server_3
5 | console_1,console_2,console_3
6 |
7 |
8 |
9 | servers
10 | 2
11 | true
12 | 2
13 |
14 |
15 | servers
16 | 1
17 | true
18 | true
19 |
20 |
21 |
22 |
23 |
24 | 1
25 | LESS_LOADED
26 | CONTINUE
27 | RESTART_PROCESS
28 |
29 |
30 | model_services
31 | 3
32 |
33 |
34 | check_data_bus
35 | 2
36 |
37 |
38 | model_services
39 |
40 |
41 | check_data_bus
42 |
43 |
44 |
45 |
46 |
47 |
48 | SINGLE_INSTANCE
49 | #,consoles
50 | 3
51 | CONTINUE
52 |
53 |
54 | 2
55 | 8
56 |
57 |
58 | check_data_bus
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/SupervisorLogResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 |
20 | /**
21 | * The Class SupervisorLogResult.
22 | *
23 | * It gives a structured form to the process information received from a XML-RPC.
24 | */
25 | public class SupervisorLogResult {
26 |
27 | /** The log bytes. */
28 | private String bytes;
29 |
30 | /** The log offset. */
31 | private Integer offset;
32 |
33 | /** The log overflow. */
34 | private Boolean overflow;
35 |
36 | /**
37 | * The constructor gets all information from an HashMap.
38 | *
39 | * @param HashMap addressInfo: The untyped structure got from the XML-RPC.
40 | */
41 | public SupervisorLogResult(final Object[] objectsArray) {
42 | this.bytes = (String) objectsArray[0];
43 | this.offset = (Integer) objectsArray[1];
44 | this.overflow = (Boolean) objectsArray[2];
45 | }
46 |
47 | /**
48 | * The getBytes method returns the log bytes.
49 | *
50 | * @return String: The log bytes.
51 | */
52 | public String getBytes() {
53 | return this.bytes;
54 | }
55 |
56 | /**
57 | * The getOffset method returns the offset.
58 | *
59 | * @return Integer: The log offset.
60 | */
61 | public Integer getOffset() {
62 | return this.offset;
63 | }
64 |
65 | /**
66 | * The getGroupName method returns the log overflow.
67 | *
68 | * @return Boolean: The log overflow.
69 | */
70 | public Boolean getOverflow() {
71 | return this.overflow;
72 | }
73 |
74 | /**
75 | * The toString method returns a printable form of the contents of the instance.
76 | *
77 | * @return String: The contents of the instance.
78 | */
79 | public String toString() {
80 | return "SupervisorLogResult(offset=" + this.offset
81 | + " overflow=" + this.overflow + " bytes=" + this.bytes + ")";
82 | }
83 |
84 | }
85 |
86 |
--------------------------------------------------------------------------------
/supvisors/client/java/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ${version}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/SupervisorState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 | import java.util.HashMap;
20 |
21 |
22 | /**
23 | * The Class SupervisorState.
24 | *
25 | * It gives a structured form to the supervisor state received from a XML-RPC.
26 | */
27 | public class SupervisorState {
28 |
29 | /**
30 | * The State enumeration for Supervisor.
31 | *
32 | * FATAL is used when Supervisor has experienced a serious error.
33 | * RUNNING is used when Supervisor is working normally.
34 | * RESTARTING is used when Supervisor is in the process of restarting.
35 | * SHUTDOWN is used when Supervisor is in the process of shutting down.
36 | */
37 | public enum State {
38 | FATAL(2),
39 | RUNNING(1),
40 | RESTARTING(0),
41 | SHUTDOWN(-1);
42 |
43 | /** The state code. */
44 | private int stateCode;
45 |
46 | /** The constructor links the state code to the state name. */
47 | private State(final int stateCode) {
48 | this.stateCode = stateCode;
49 | }
50 | }
51 |
52 | /** The supervisor state. */
53 | private State state;
54 |
55 | /**
56 | * The constructor gets the state information from an HashMap.
57 | *
58 | * @param HashMap stateInfo: The untyped structure got from the XML-RPC.
59 | */
60 | public SupervisorState(HashMap stateInfo) {
61 | this.state = State.valueOf((String) stateInfo.get("statename"));
62 | }
63 |
64 | /**
65 | * The getState method returns the state of supervisor.
66 | *
67 | * @return State: The state of the supervisor.
68 | */
69 | public State getState() {
70 | return this.state;
71 | }
72 |
73 | /**
74 | * The toString method returns a printable form of the contents of the instance.
75 | *
76 | * @return String: The contents of the instance.
77 | */
78 | public String toString() {
79 | return "SupervisorState(state=" + this.state + ")";
80 | }
81 |
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/SupvisorsStateModes.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 | import java.util.HashMap;
20 |
21 | /**
22 | * The Class SupvisorsStateModes.
23 | *
24 | * It gives a structured form to the Supvisors Instance state & modes received from a XML-RPC.
25 | */
26 |
27 | public class SupvisorsStateModes extends SupvisorsCommonStateModes {
28 |
29 | /** True if the Supvisors instance has starting jobs in progress. */
30 | private Boolean starting_jobs;
31 |
32 | /** True if the Supvisors instance has stopping jobs in progress. */
33 | private Boolean stopping_jobs;
34 |
35 | /**
36 | * This constructor gets all information from an HashMap.
37 | *
38 | * @param HashMap instanceInfo: The untyped structure got from the XML-RPC.
39 | */
40 | public SupvisorsStateModes(HashMap info) {
41 | super(info);
42 | this.starting_jobs = (Boolean) info.get("starting_jobs");
43 | this.stopping_jobs = (Boolean) info.get("stopping_jobs");
44 | }
45 |
46 | /**
47 | * The hasStartingJobs method returns True if the Supvisors instance has jobs in progress in its Starter.
48 | *
49 | * @return Boolean: The starting jobs progress.
50 | */
51 | public Boolean hasStartingJobs() {
52 | return this.starting_jobs;
53 | }
54 |
55 | /**
56 | * The hasStoppingJobs method returns True if the Supvisors instance has jobs in progress in its Stopper.
57 | *
58 | * @return Boolean: The stopping jobs progress.
59 | */
60 | public Boolean hasStoppingJobs() {
61 | return this.stopping_jobs;
62 | }
63 |
64 | /**
65 | * The toString method returns a printable form of the SupvisorsStateModes instance.
66 | *
67 | * @return String: The contents of the SupvisorsStateModes.
68 | */
69 | public String toString() {
70 | return "SupvisorsStateModes(" + super.toString()
71 | + " startingJobs=" + this.starting_jobs
72 | + " stoppingJobs=" + this.stopping_jobs + ")";
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/supvisors/ui/css/button.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Button styles
19 | */
20 | .button {
21 | display: inline-block;
22 | padding: 2px 4px;
23 | margin-bottom: 2px;
24 | background-image: linear-gradient(180deg, var(--vlight2-color), var(--vlight1-color));
25 | border: none;
26 | border-radius: 6px;
27 | box-shadow: 0 2px #666;
28 | color: var(--text-color);
29 | font-size: .8em;
30 | text-decoration: none;
31 | text-align: center;
32 | outline: none;
33 | }
34 |
35 | .button.on {
36 | cursor: pointer;
37 | }
38 |
39 | .button.off {
40 | cursor: not-allowed;
41 | color: var(--light2-color);
42 | background-color: var(--light1-color);
43 | background-image: none;
44 | box-shadow: 0 2px #555;
45 | }
46 |
47 | .button.on:hover {
48 | background-image: linear-gradient(180deg, var(--light1-color), var(--light2-color));
49 | }
50 |
51 | .button.on:active {
52 | background-image: linear-gradient(180deg, var(--dark1-color), var(--dark2-color));
53 | transform: translateY(1px);
54 | box-shadow: 0 1px #777, 0 -1px #777;
55 | }
56 |
57 | .button.active {
58 | color: var(--selected-color);
59 | background-image: linear-gradient(180deg, var(--dark1-color), var(--dark2-color));
60 | box-shadow: 0 1px #777, 0 -1px #777;
61 | transform: translateY(1px);
62 | }
63 |
64 | .button.active.on:hover {
65 | background-image: linear-gradient(180deg, var(--light1-color), var(--light2-color));
66 | }
67 |
68 | .button.active.on:active {
69 | background-image: linear-gradient(180deg, var(--vlight2-color), var(--vlight1-color));
70 | box-shadow: 0 2px #666;
71 | transform: translateY(-1px);
72 | }
73 |
74 | /* Button group based on button definition above */
75 | div.button_group {
76 | display: flex;
77 | flex-direction: row;
78 | justify-content: center;
79 | align-items: center;
80 | margin: 0 auto;
81 | }
82 |
83 | div.button_group .button:not(:first-child) {
84 | border-top-left-radius: 0;
85 | border-bottom-left-radius: 0;
86 | margin-left: 1px;
87 | }
88 |
89 | div.button_group .button:not(:last-child) {
90 | border-top-right-radius: 0;
91 | border-bottom-right-radius: 0;
92 | }
93 |
--------------------------------------------------------------------------------
/supvisors/tests/test_plot.py:
--------------------------------------------------------------------------------
1 | # ======================================================================
2 | # Copyright 2017 Julien LE CLEACH
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ======================================================================
16 |
17 | import pytest
18 |
19 | pytest.importorskip('matplotlib', reason='cannot test as optional matplotlib is not installed')
20 |
21 | from supvisors.web.plot import *
22 | from supvisors.web.viewimage import StatsImage
23 |
24 |
25 | def test_plot(logger_instance):
26 | """ Test a simple plot.
27 | Complex to test anything. Just check that there is no exception. """
28 | plot = StatisticsPlot(logger_instance)
29 | assert plot.ydata == {}
30 | # add series of data
31 | plot.add_timeline([0, 1, 2])
32 | plot.add_plot('dummy_title_1', 'unit_1', [1, 2, 3])
33 | plot.add_plot('dummy_title_2', 'unit_2', [10, 20, 30])
34 | assert plot.xdata == [0, 1, 2]
35 | assert plot.ydata == {('dummy_title_1', 'unit_1'): [1, 2, 3], ('dummy_title_2', 'unit_2'): [10, 20, 30]}
36 | # export image in buffer
37 | contents = StatsImage()
38 | plot.export_image(contents)
39 |
40 |
41 | def test_plot_error(mocker, logger_instance):
42 | """ Check the exception handling when saving the figure. """
43 | plot = StatisticsPlot(logger_instance)
44 | assert plot.ydata == {}
45 | # add series of data
46 | plot.add_timeline([0, 1, 2])
47 | plot.add_plot('dummy_title_1', 'unit_1', [1, 2, 3])
48 | plot.add_plot('dummy_title_2', 'unit_2', [10, 20, 30])
49 | assert plot.ydata == {('dummy_title_1', 'unit_1'): [1, 2, 3], ('dummy_title_2', 'unit_2'): [10, 20, 30]}
50 | # mock the savefig function
51 | mocker.patch.object(plt, 'savefig', side_effect=RuntimeError)
52 | # export image in buffer
53 | contents = StatsImage()
54 | plot.export_image(contents)
55 |
56 |
57 | def test_get_range():
58 | """ Test a simple plot.
59 | Complex to test anything. Just check that there is no exception. """
60 | # first test
61 | min_range, max_range = StatisticsPlot.get_range([10, 50, 30, 90])
62 | assert pytest.approx(min_range) == 2.0
63 | assert pytest.approx(max_range) == 118.0
64 | # second test
65 | min_range, max_range = StatisticsPlot.get_range([0, 100])
66 | assert pytest.approx(min_range) == 0.0
67 | assert pytest.approx(max_range) == 135.0
68 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/supvisors_rules_mc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 3
6 | true
7 | 10
8 |
9 |
10 | 2
11 | true
12 | true
13 |
14 |
15 | 1
16 | true
17 | 2
18 |
19 |
20 |
21 |
22 |
23 | SINGLE_INSTANCE
24 | @SERVER
25 | 1
26 | LESS_LOADED
27 | STOP
28 |
29 |
30 | model_services
31 | 4
32 |
33 |
34 | check_data_bus
35 | 3
36 |
37 |
38 | model_services
39 |
40 |
41 | check_data_bus
42 |
43 |
44 | data_bus
45 | RESTART_APPLICATION
46 |
47 |
48 |
49 |
50 |
51 |
52 | SINGLE_INSTANCE
53 | @CONSOLE
54 | LOCAL
55 | CONTINUE
56 |
57 |
58 | 3
59 | 8
60 |
61 |
62 | check_data_bus
63 |
64 |
65 | data_bus
66 | STOP_APPLICATION
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/SupervisorConfigUpdates.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 | import java.util.List;
20 |
21 | /**
22 | * The class SupervisorConfigUpdates.
23 | *
24 | * It gives a structured form to the process rules received from a XML-RPC.
25 | */
26 | public class SupervisorConfigUpdates {
27 |
28 | /** The list of added configurations. */
29 | private List added;
30 |
31 | /** The list of changed configurations. */
32 | private List changed;
33 |
34 | /** The list of removed configurations. */
35 | private List removed;
36 |
37 | /**
38 | * The constructor gets all information from an object array.
39 | *
40 | * @param Object[] objectArray: The untyped structure got from the XML-RPC.
41 | */
42 | public SupervisorConfigUpdates(final Object[] objectsArray) {
43 | // real structure is enclosed in array
44 | Object[] array = (Object[]) objectsArray[0];
45 | this.added = DataConversion.arrayToStringList((Object[]) array[0]);
46 | this.changed = DataConversion.arrayToStringList((Object[]) array[1]);
47 | this.removed = DataConversion.arrayToStringList((Object[]) array[2]);
48 | }
49 |
50 | /**
51 | * The getAdded method returns the list of added configurations.
52 | *
53 | * @return List: The list of added configurations.
54 | */
55 | public List getAdded() {
56 | return this.added;
57 | }
58 |
59 | /**
60 | * The getChanged method returns the list of changed configurations.
61 | *
62 | * @return List: The list of changed configurations.
63 | */
64 | public List getChanged() {
65 | return this.changed;
66 | }
67 |
68 | /**
69 | * The getRemoved method returns the list of removed configurations.
70 | *
71 | * @return List: The list of removed configurations.
72 | */
73 | public List getRemoved() {
74 | return this.removed;
75 | }
76 |
77 | /**
78 | * The toString method returns a printable form of the contents of the instance.
79 | *
80 | * @return String: The contents of the instance.
81 | */
82 | public String toString() {
83 | return "SupervisorConfigUpdates(added=" + this.added
84 | + " changed=" + this.changed + " removed=" + this.removed + ")";
85 | }
86 |
87 | }
88 |
89 |
--------------------------------------------------------------------------------
/supvisors/test/scripts/supervisorctl_test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | function sendRequest() {
4 | echo "===================================================================="
5 | echo "# Testing: supervisorctl" "$@"
6 | echo "===================================================================="
7 | supervisorctl help "$1"
8 | echo
9 | supervisorctl "$@"
10 | echo
11 | }
12 |
13 | sleep 1
14 |
15 | # print global help
16 | sendRequest help
17 |
18 | # change log level
19 | sendRequest loglevel error
20 |
21 | # status requests
22 | sendRequest sversion
23 | sendRequest sstate
24 | sendRequest sstate all
25 | sendRequest sstate supv-01
26 | sendRequest master
27 | sendRequest strategies
28 | sendRequest stats_status
29 |
30 | sendRequest instance_status
31 | sendRequest instance_status 17.0.1.11:60000
32 |
33 | sendRequest application_info
34 | sendRequest application_info database
35 |
36 | sendRequest application_rules
37 | sendRequest application_rules database
38 | sendRequest application_rules database player
39 |
40 | sendRequest sstatus
41 | sendRequest sstatus database:*
42 | sendRequest sstatus database:movie_server_01 database:movie_server_02 database:movie_server_03
43 |
44 | sendRequest local_status
45 | sendRequest local_status database:*
46 | sendRequest local_status database:movie_server_01 database:movie_server_02 database:movie_server_03
47 |
48 | sendRequest process_rules
49 | sendRequest process_rules database:movie_server_02
50 | sendRequest process_rules database:movie_server_02 player:movie_player
51 |
52 | # command requests on processes
53 | sendRequest test_start_process CONFIG my_movies:converter_01
54 | sendRequest start_process CONFIG my_movies:converter_01
55 | sendRequest restart_process LESS_LOADED my_movies:converter_01
56 | sendRequest stop_process my_movies:converter_01
57 | sendRequest start_any_process CONFIG converter
58 |
59 | sendRequest start_args my_movies:converter_02 -x 3 -d \'additional arguments\'
60 | sleep 3
61 |
62 | sendRequest start_process_args MOST_LOADED my_movies:converter_02 -x 3 -d \'additional arguments\'
63 | sleep 3
64 |
65 | sendRequest start_any_process_args CONFIG converter -x 3
66 | sleep 3
67 |
68 | sendRequest all_start_args my_movies:converter_05 -x 3
69 | sleep 3
70 |
71 | sendRequest all_start my_movies:converter_12
72 | sleep 3
73 |
74 | # check conciliation
75 | sendRequest conflicts
76 | sendRequest conciliate INFANTICIDE
77 | sleep 10
78 |
79 | # Supervisor enhancements
80 | sendRequest lazy_update_numprocs converter 12
81 | sendRequest update_numprocs converter 10
82 | sendRequest update_numprocs converter 15
83 | sendRequest disable converter
84 | sendRequest enable converter
85 |
86 | # command requests on applications
87 | sendRequest restart_application MOST_LOADED database
88 | sendRequest stop_application database
89 | sendRequest test_start_application LESS_LOADED database
90 | sendRequest start_application LESS_LOADED database
91 |
92 | # command requests on Supervisor
93 | sendRequest sreload
94 | sleep 40
95 | sendRequest sshutdown
96 |
--------------------------------------------------------------------------------
/supvisors/ui/css/header.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Supvisors common style for page header
19 | */
20 | #right_side header {
21 | flex: 1;
22 | display: flex;
23 | flex-direction: row;
24 | min-height: 100px;
25 | max-height: 100px;
26 | padding: 0 10px;
27 | justify-content: space-between;
28 | align-items: center;
29 | }
30 |
31 | #right_side header .card {
32 | display: flex;
33 | height: 95%;
34 | }
35 |
36 | #right_side header .line_separator {
37 | flex: 1;
38 | display: flex;
39 | margin: 0 10px;
40 | border-bottom: 2px dotted var(--text-color);
41 | }
42 |
43 | /* Style for user software elements */
44 | #right_side header .card div img {
45 | max-height: 95px;
46 | }
47 |
48 | /* Style for instance status (applicable to SupvisorsInstanceStatus and Application) */
49 | #instance_status table.status {
50 | border: none;
51 | background: transparent;
52 | }
53 |
54 | #instance_status table.status th, #instance_status table.status td {
55 | border: none;
56 | background: transparent;
57 | }
58 |
59 | #instance_status table.status td {
60 | text-align: center;
61 | }
62 |
63 | .table_main {
64 | font-size: 1em;
65 | text-align: center;
66 | }
67 |
68 | .table_title {
69 | text-align: right;
70 | }
71 |
72 | code.hstate {
73 | display: inline-block;
74 | padding: 3px 8px;
75 | font-size: 1.6em;
76 | border-radius: 6px;
77 | text-shadow: 3px 3px 4px black;
78 | background: var(--vlight1-color);
79 | }
80 |
81 | /* Style for option boxes */
82 | div.option_box {
83 | margin: 0 5px;
84 | border: 3px ridge var(--border-color);
85 | font-size: .7em;
86 | }
87 |
88 | div.option_box div.option_title {
89 | background-color: var(--th-color);
90 | font-weight: bold;
91 | text-align: center;
92 | border-bottom: solid 1px var(--border-color);
93 | padding: 3px 10px;
94 | }
95 |
96 | div.option_box div.button_group {
97 | background-image: linear-gradient(180deg, var(--light2-color), var(--light1-color));
98 | padding: 3px 10px;
99 | }
100 |
101 | /* Style for action buttons */
102 | table.buttons {
103 | border: none;
104 | background: transparent;
105 | }
106 |
107 | table.buttons td {
108 | border: none;
109 | padding: 2px 3px;
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/supvisors/client/java/org/supvisors/common/SupvisorsStatus.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.supvisors.common;
18 |
19 | import java.util.Arrays;
20 | import java.util.HashMap;
21 | import java.util.List;
22 | import java.util.Map;
23 |
24 |
25 | /**
26 | * The Class SupvisorsStatus.
27 | *
28 | * It gives a structured form to the supervisor state received from a XML-RPC.
29 | */
30 | public class SupvisorsStatus extends SupvisorsCommonStateModes {
31 |
32 | /** The identifiers of where starting jobs are in progress. */
33 | private List starting_jobs;
34 |
35 | /** The identifiers of where stopping jobs are in progress. */
36 | private List stopping_jobs;
37 |
38 | /**
39 | * The constructor gets the state information from an HashMap.
40 | *
41 | * @param HashMap stateInfo: The untyped structure got from the XML-RPC.
42 | */
43 | public SupvisorsStatus(HashMap info) {
44 | super(info);
45 | Object[] startingJobs = (Object[]) info.get("starting_jobs");
46 | this.starting_jobs = DataConversion.arrayToStringList(startingJobs);
47 | Object[] stoppingJobs = (Object[]) info.get("stopping_jobs");
48 | this.stopping_jobs = DataConversion.arrayToStringList(stoppingJobs);
49 | }
50 |
51 | /**
52 | * The getStartingJobs method returns the identifiers of the Supvisors instances where starting jobs are in progress.
53 | *
54 | * @return List: The list of identifiers where Supvisors has starting jobs.
55 | */
56 | public List getStartingJobs() {
57 | return this.starting_jobs;
58 | }
59 |
60 | /**
61 | * The getStoppingJobs method returns the identifiers of the Supvisors instances where stopping jobs are in progress.
62 | *
63 | * @return List: The list of identifiers where Supvisors has stopping jobs.
64 | */
65 | public List getStoppingJobs() {
66 | return this.stopping_jobs;
67 | }
68 |
69 | /**
70 | * The toString method returns a printable form of the SupvisorsStatus instance.
71 | *
72 | * @return String: The contents of the SupvisorsStatus.
73 | */
74 | public String toString() {
75 | return "SupvisorsStatus(" + super.toString()
76 | + " startingJobs=" + this.starting_jobs
77 | + " stoppingJobs=" + this.stopping_jobs + ")";
78 | }
79 |
80 | }
81 |
82 |
--------------------------------------------------------------------------------
/supvisors/ui/css/process_table.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Julien LE CLEACH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /*
18 | * Supvisors style for pages displaying a process table
19 | */
20 |
21 | #process_contents {
22 | display: flex;
23 | flex: 1;
24 | flex-direction: row;
25 | justify-content: space-around;
26 | overflow: auto;
27 | margin: 5px;
28 | }
29 |
30 | #process_left_side {
31 | overflow: auto;
32 | padding-right: 12px;
33 | }
34 |
35 | /* process table */
36 | .process_table {
37 | font-family: Verdana, Arial, sans-serif;
38 | text-align: justify;
39 | margin-right: 5px;
40 | overflow: auto;
41 | }
42 |
43 | .process_table thead, .process_table thead tr {
44 | border: solid 1px var(--border-color);
45 | }
46 |
47 | .process_table thead th {
48 | position: sticky;
49 | top: 0;
50 | z-index: 20;
51 | }
52 |
53 | .process_table tbody tr:last-child td {
54 | border-bottom: none;
55 | }
56 |
57 | .process_table tfoot th {
58 | position: sticky;
59 | bottom: 0;
60 | z-index: 20;
61 | }
62 |
63 | table .name {
64 | width: 200px;
65 | }
66 |
67 | table .state {
68 | width: 50px;
69 | }
70 |
71 | table .desc {
72 | width: 250px;
73 | }
74 |
75 | .shex {
76 | vertical-align: top;
77 | }
78 |
79 | .centered {
80 | text-align: center;
81 | }
82 |
83 | .expected {
84 | font-style: italic;
85 | }
86 |
87 | tbody.hoverable tr:hover, tbody.hoverable tr:hover td:not(.state_cell) {
88 | background-color: var(--navbg-color);
89 | background-image: none;
90 | }
91 |
92 | /*
93 | * Related to the detailed statistics
94 | */
95 | #process_right_side {
96 | max-width: 500px;
97 | align-items: center;
98 | margin-right: 10px;
99 | }
100 |
101 | #process_right_side div.card {
102 | text-align: center;
103 | width: 400px;
104 | margin-top: 6px;
105 | margin-bottom: 10px;
106 | box-shadow: 0px 0px 6px black;
107 | }
108 |
109 | #process_right_side div.card .selected {
110 | color: var(--selected-color);
111 | }
112 |
113 | .stats_contents {
114 | flex: 0;
115 | display: flex;
116 | width: 450px;
117 | margin-bottom: 10px;
118 | flex-direction: row;
119 | justify-content: space-evenly;
120 | }
121 |
122 | .stats_contents div>* {
123 | margin-left: 5px;
124 | }
125 |
126 | .stats_contents td {
127 | text-align: center;
128 | }
129 |
--------------------------------------------------------------------------------
/supvisors/test/use_cases/scenario_2/etc/supvisors_rules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | server_1,server_2,server_3
5 | console_1,console_2,console_3
6 |
7 |
8 |
9 | 3
10 | true
11 | 10
12 |
13 |
14 | 2
15 | true
16 | true
17 |
18 |
19 | 1
20 | true
21 | 2
22 |
23 |
24 |
25 |
26 |
27 | SINGLE_INSTANCE
28 | servers
29 | 1
30 | LESS_LOADED
31 | STOP
32 |
33 |
34 | model_services
35 | 4
36 |
37 |
38 | check_data_bus
39 | 3
40 |
41 |
42 | model_services
43 |
44 |
45 | check_data_bus
46 |
47 |
48 | data_bus
49 | RESTART_APPLICATION
50 |
51 |
52 |
53 |
54 |
55 |
56 | SINGLE_INSTANCE
57 | consoles
58 | LOCAL
59 | CONTINUE
60 |
61 |
62 | 3
63 | 8
64 |
65 |
66 | check_data_bus
67 |
68 |
69 | data_bus
70 | STOP_APPLICATION
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/supvisors/test/scripts/process_app.py:
--------------------------------------------------------------------------------
1 | # ======================================================================
2 | # Copyright 2016 Julien LE CLEACH
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ======================================================================
16 |
17 | import os
18 |
19 | from sys import stderr
20 | from tkinter import *
21 |
22 |
23 | class ProcessAppTk(Tk):
24 |
25 | cpt = 1
26 |
27 | def __init__(self, namespec, description):
28 | """ Initialization of the attributes. """
29 | Tk.__init__(self, None)
30 | print(f'Starting {namespec} in {os.getenv("SUPERVISOR_SERVER_URL")}')
31 | self.title('Supvisors')
32 | self.grid()
33 | # create main form
34 | form_window = PanedWindow(self, orient=VERTICAL)
35 | # display namespec into a PanedWindow
36 | main_window = PanedWindow(form_window, orient=VERTICAL)
37 | main_window.add(Label(main_window, text=f'Supvisors namespec: {namespec}'))
38 | if description:
39 | main_window.add(Label(main_window, text=f'Supvisors description: {description}'))
40 | # talk action
41 | main_window.add(Button(self, text='Talk', command=self.talk))
42 | # add window to form and pack it
43 | form_window.add(main_window)
44 | form_window.pack()
45 | # close action
46 | Button(self, text=u"Close", command=self.quit).pack(side=BOTTOM, padx=10, pady=2)
47 | # window properties
48 | self.grid_columnconfigure(0, weight=1)
49 | self.resizable(False, False)
50 |
51 | @staticmethod
52 | def talk():
53 | print('Talking seq=%d' % ProcessAppTk.cpt, flush=True)
54 | print('[ERR] Talking seq=%d' % ProcessAppTk.cpt, file=stderr, flush=True)
55 | ProcessAppTk.cpt = ProcessAppTk.cpt + 1
56 |
57 | def quit(self):
58 | print('Quit called')
59 | Tk.quit(self)
60 |
61 |
62 | if __name__ == "__main__":
63 | # get arguments
64 | import argparse
65 |
66 | parser = argparse.ArgumentParser(description='Start a dummy window named with a namespec.')
67 | parser.add_argument('-n', '--namespec', required=True, help='the namespec of the program')
68 | parser.add_argument('-x', '--xkill', type=int, metavar='SEC', help='kill the window after SEC seconds')
69 | parser.add_argument('-d', '--description', metavar='DESC', help='an additional description')
70 | args = parser.parse_args()
71 | # create window
72 | root = ProcessAppTk(args.namespec, args.description)
73 | # create auto-kill task
74 | if args.xkill is not None:
75 | root.after(args.xkill * 1000, root.quit)
76 | # start main loop
77 | root.mainloop()
78 |
--------------------------------------------------------------------------------
/docs/faq.rst:
--------------------------------------------------------------------------------
1 | .. _faq:
2 |
3 | Frequent Asked Questions
4 | ========================
5 |
6 | How to change the Supvisors Web UI ?
7 | ------------------------------------
8 |
9 | If the user is considering structural updates of the |Supvisors| Web UI, such as:
10 |
11 | * adding/removing information,
12 | * changing the ``XHTML`` elements structure,
13 | * adding ``Javascript`` code,
14 |
15 | the recommended way to proceed is obviously to work on a fork and update the ``XHTML``, ``CSS`` and ``Python`` code
16 | as needed.
17 |
18 | However, if the updates under consideration are involving ``CSS`` only, such as:
19 |
20 | * updating resources (colors, fonts, font sizes, bitmaps),
21 | * updating object feedbacks (hover, active, focus),
22 | * reorganizing HTML elements (``div`` sizes and positions),
23 | * hiding some existing parts,
24 |
25 | the following hint will provide a way to do it without updating |Supvisors|, based on a simple bootstrap
26 | and monkeypatch.
27 |
28 | Every Supvisors ``XHTML`` page include a style instruction that can be used to inject user ``CSS`` by code.
29 | It is placed after the inclusion of all ``CSS`` files, so that the user ``CSS`` may overwrite anything.
30 |
31 | .. code-block:: html
32 |
33 |
34 |
35 | The bootstrap consists in inserting some user code between the |Supervisor| plugin factory and the |Supvisors| plugin
36 | creation. The code will create the |Supvisors| plugin and monkeypatch the ``ViewHandler.write_style`` method,
37 | so that the style instruction above is filled with ``CSS`` instructions that can be hardcoded as shown below
38 | or simply read from a file.
39 |
40 | .. code-block:: python
41 |
42 | from supvisors.plugin import make_supvisors_rpcinterface
43 | from supvisors.web.viewhandler import ViewHandler
44 |
45 | USER_CSS = """
46 | div {
47 | background-color: black;
48 | }
49 | """
50 |
51 | def write_style(self, root):
52 | """ Insert additional CSS instructions into the pages. """
53 | root.findmeld('style_mid').content(USER_CSS)
54 |
55 | def make_user_rpcinterface(supervisord, **config):
56 | """ Create the Supvisors plugin and monkeypatch the write_style method. """
57 | intf = make_supvisors_rpcinterface(supervisord, **config)
58 | ViewHandler.write_style = write_style
59 | return inf
60 |
61 |
62 | Finally, in the |Supervisor| configuration file, the |Supvisors| plugin has to be configured using the bootstrap
63 | instead of the |Supvisors| usual function.
64 |
65 | .. code-block:: ini
66 |
67 | [rpcinterface:supvisors]
68 | ;supervisor.rpcinterface_factory = supvisors.plugin:make_supvisors_rpcinterface
69 | supervisor.rpcinterface_factory = :make_user_rpcinterface
70 |
71 |
72 | .. important::
73 |
74 | Before starting the |Supervisor| daemon, ensure that the bootstrap is visible in the :command:`Python` context.
75 | It can be part of an installed :command:`Python` package or just set in the ``PYTHONPATH`` environment variable.
76 |
77 | .. code-block:: bash
78 |
79 | [bash] > export PYTHONPATH=:${PYTHONPATH}
80 | [bash] > supervisord
81 |
82 |
83 | .. include:: common.rst
84 |
--------------------------------------------------------------------------------
/supvisors/tools/apis/utils.py:
--------------------------------------------------------------------------------
1 | # ======================================================================
2 | # Copyright 2022 Julien LE CLEACH
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # ======================================================================
16 |
17 | import os
18 | from argparse import ArgumentParser
19 | from typing import Dict
20 | from urllib.parse import urlparse
21 |
22 | from supvisors.utils import parse_docstring
23 |
24 |
25 | def get_docstring_description(func) -> str:
26 | """ Extract the first part of the docstring. """
27 | docstring = parse_docstring(func.__doc__)
28 | return docstring[0][4]
29 |
30 |
31 | def get_docstring_parameters(func) -> Dict:
32 | """ Extract the parameters from the docstring.
33 | Supervisor and Supvisors have different formats. """
34 | docstring = parse_docstring(func.__doc__)
35 | return {entry[3]: entry[4] for entry in docstring if entry[1] == 'param'}
36 |
37 |
38 | # Argument parsing
39 | def is_url(arg_parser, arg):
40 | """ Test if the argument is a well-formatted URL.
41 |
42 | :param arg_parser: the argument parser
43 | :param arg: the argument to test
44 | :return: True if the argument is a folder
45 | """
46 | try:
47 | result = urlparse(arg)
48 | if all([result.scheme, result.netloc, result.port]):
49 | return arg
50 | except ValueError as exc:
51 | arg_parser.error(f'Could not parse the URL provided: {arg} ({exc})')
52 | arg_parser.error(f'The URL provided is invalid: {arg}')
53 |
54 |
55 | def parse_args(args):
56 | """ Parse arguments got from the command line.
57 |
58 | :param args: the command line arguments
59 | :return: the parsed arguments
60 | """
61 | # check if this process has been spawned by Supervisor
62 | supervisor_url = os.environ.get('SUPERVISOR_SERVER_URL')
63 | # create argument parser
64 | parser = ArgumentParser(description='Start a Flask application to interact with Supvisors', add_help=False)
65 | parser.add_argument('--help', action='help', help='show this help message and exit')
66 | parser.add_argument('-u', '--supervisor_url', type=lambda x: is_url(parser, x),
67 | default=supervisor_url, required=not supervisor_url,
68 | help='the Supervisor URL, required if supvisorsflask is not spawned by Supervisor')
69 | parser.add_argument('-h', '--host', type=str, help='the Flask server IP address')
70 | parser.add_argument('-p', '--port', type=int, help='the Flask server port number')
71 | parser.add_argument('-d', '--debug', action='store_true', help='the Flask Debug mode')
72 | # parse arguments from command line
73 | args = parser.parse_args(args)
74 | return args
75 |
--------------------------------------------------------------------------------