supervisor cluster management

Introduction to Cesi

CeSi (Centralized Supervisor Interface) is a Web UI officially recommended by Supervisor for centralized management of Supervisor instances. This tool is written in Python

Cesi installation steps

export CESI_SETUP_PATH=~/cesi
mkdir ${CESI_SETUP_PATH}
cd ${CESI_SETUP_PATH}
wget https://github.com/gamegos/cesi/releases/download/v2.6.7/cesi-extended.tar.gz -O cesi.tar.gz
tar -xvf cesi.tar.gz
python3 -m venv venv
source venv/bin/activate
pip3 install -r requirements.txt
pip3 install –upgrade pip
pip install -r requirements.txt
python3 ${CESI_SETUP_PATH}/cesi/run.py –config-file ${CESI_SETUP_PATH}/defaults/cesi.conf.toml
pip3 install –upgrade sqlalchemy==1.3.23
python3 ${CESI_SETUP_PATH}/cesi/run.py –config-file ${CESI_SETUP_PATH}/defaults/cesi.conf.toml

[root@localhost defaults]# vi cesi.conf.toml

# This is the main CeSI toml configuration file. It contains CeSI web application and
# supervisord information to connect

# This is the CeSI's own configuration.
[cesi]
# Database Uri
database = "sqlite:///users.db" # Relative path
#Etc
# This is the main CeSI toml configuration file. It contains CeSI web application and
# supervisord information to connect

# This is the CeSI's own configuration.
[cesi]
# Database Uri
database = "sqlite:///users.db" # Relative path
#Etc
#database = "sqlite:opt/cesi/< version >/users.db" # Absolute path
#database = "postgres://<user>:<password>@localhost:5432/<database_name>"
#database = "mysql + pymysql://<user>:<password>@localhost:3306/<database_name>"
activity_log = "activity.log" # File path for CeSI logs
admin_username = "admin" # Username of admin user
admin_password = "admin" # Password of admin user

# This is the definition section for new supervisord node.
# [[nodes]]
# name = "api" # (String) Unique name for supervisord node.
# environment = "" # (String) The environment name provides logical grouping of supervisord nodes. It can be used as filtering option in the UI.
# username = "" # (String) Username of the XML-RPC interface of supervisord Set nothing if no username is configured
# password = "" # (String) Password of the XML-RPC interface of supervisord. Set nothing if no username is configured
# host = "127.0.0.1" # (String) Host of the XML-RPC interface of supervisord
# port = "9001" # (String) Port of the XML-RPC interface of supervisord

# Default supervisord nodes
[[nodes]]
name = "102-server"
environment = "102"
username = ""
password = ""
host = "192.168.30.102"
port = "9001"

[[nodes]]
name = "105-server"
environment = "105"
username = ""
password = ""
host = "192.168.30.105"
port = "9001"

cesi.conf.toml configuration

After the installation is complete, an error message appears when logging in for the first time when opening the web page.

Cesi normal management

Can remotely operate the supervisor on the connected host

Successful remote start and stop service

Ansible batch installation supervisor service

Ansible is installed through the source code package and automatically registered as a service. Then ansible can operate the installed service through the service module.

- name: Create taishi dir
  file: path={<!-- -->{ taishi_dir }} state=directory owner={<!-- -->{ taishi_user }} group={<!-- -->{ taishi_user }} recurse=yes
  tags: base

- name: Create logs dir
  file: path={<!-- -->{ taishi_dir }}/logs state=directory owner={<!-- -->{ taishi_user }} group={<!-- -->{ taishi_user }} recurse =yes
  tags: base

- name: Create etc dir
  file: path={<!-- -->{ taishi_dir }}/etc state=directory owner={<!-- -->{ taishi_user }} group={<!-- -->{ taishi_user }} recurse =yes
  tags: base

- name: Create supervisord dir
  file: path={<!-- -->{ taishi_dir }}/etc/supervisord state=directory owner={<!-- -->{ taishi_user }} group={<!-- -->{ taishi_user } } recurse=yes
  tags: base


- name: Create tmp dir
  file: path={<!-- -->{ taishi_dir }}/tmp state=directory owner={<!-- -->{ taishi_user }} group={<!-- -->{ taishi_user }} recurse =yes
  tags: base

- name: Copy the supervisorcnf to {<!-- -->{ groups["all"] }}
  template: src=supervisord.conf.j2 dest="{<!-- -->{ taishi_dir }}/etc/supervisord.conf" owner={<!-- -->{ taishi_user }} group={<! -- -->{ taishi_user }} mode=0755
  tags: supervisor

- name: Copy the start_taishi to {<!-- -->{ groups["all"] }}
  template: src=start_taishi.sh.j2 dest="{<!-- -->{ taishi_dir }}/etc/start_taishi.sh" owner={<!-- -->{ taishi_user }} group={<! -- -->{ taishi_user }} mode=0755
  tags: supervisor

- name: Copy the taishiservice to {<!-- -->{ groups["all"] }}
  template: src=taishi.service.j2 dest="/etc/systemd/system/taishi.service" owner={<!-- -->{ taishi_user }} group={<!-- -->{ taishi_user } } mode=0755
  tags: supervisor


- name: Copy elementtree to {<!-- -->{ groups["all"] }}
  copy: src=../../common/packages/supervisor/elementtree-1.2.7-20070827-preview.zip dest=/tmp
  tags: supervisor

- name: Copy meld3-0.6.5.tar.gz to {<!-- -->{ groups["all"] }}
  copy: src=../../common/packages/supervisor/meld3-0.6.5.tar.gz dest=/tmp
  tags: supervisor


- name: Copy setuptools-24.0.2.tar.gz to {<!-- -->{ groups["all"] }}
  copy: src=../../common/packages/supervisor/setuptools-24.0.2.tar.gz dest=/tmp
  tags: supervisor


- name: Copy supervisor-3.3.0.tar.gz to {<!-- -->{ groups["all"] }}
  copy: src=../../common/packages/supervisor/supervisor-3.3.0.tar.gz dest=/tmp
  tags: supervisor

- name: Install setuptools to {<!-- -->{ groups["all"] }}
  shell: "cd /tmp & amp; & amp; tar -zxvf setuptools-24.0.2.tar.gz & amp; & amp; cd setuptools-24.0.2/ & amp; & amp; python setup.py install"
  tags: supervisor

- name: Install elementtree to {<!-- -->{ groups["all"] }}
  shell: "cd /tmp & amp; & amp; easy_install elementtree-1.2.7-20070827-preview.zip"
  tags: supervisor

- name: Install meld3-0.6.5 to {<!-- -->{ groups["all"] }}
  shell: "cd /tmp & amp; & amp; easy_install meld3-0.6.5.tar.gz"
  tags: supervisor


- name: Install supervisor to {<!-- -->{ groups["all"] }}
  shell: "cd /tmp & amp; & amp; easy_install supervisor-3.3.0.tar.gz"
  tags: supervisor

- name: reload taishiservice to {<!-- -->{ groups["all"] }}
  shell: "systemctl daemon-reload"
  tags: supervisor

- name: start taishiservice to {<!-- -->{ groups["all"] }}
  service: name=taishi state=started
  tags: supervisor


- name: "chown taishi dir to {<!-- -->{ taishi_user }}"
  file: path="{<!-- -->{ taishi_dir }}" state=directory owner={<!-- -->{ taishi_user }} group={<!-- -->{ taishi_user }} recurse =yes
  tags: base

tasks/main.yml

#Taishi Enterprise supervisor config file.

[unix_http_server]
file={<!-- -->{ taishi_dir }}/tmp/supervisor.sock; (the path to the socket file)
chown={<!-- -->{ taishi_user }};

[inet_http_server] ; inet (TCP) server disabled by default
port=*:9001; (ip_address:port specifier, *:port for all iface)
;username=user ; (default is no username (open server))
;password=123 ; (default is no password (open server)

[supervisord]
logfile={<!-- -->{ taishi_dir }}/logs/supervisord.log; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10; (num of main logfile rotation backups;default 10)
loglevel=info; (log level;default info; others: debug,warn,trace)
pidfile={<!-- -->{ taishi_dir }}/tmp/supervisord.pid; (supervisord pidfile;default supervisord.pid)
nodaemon=false; (start in foreground if true;default false)
user={<!-- -->{ taishi_user }} ; (default is current user, required if root)
minfds=655350; (min. avail startup file descriptors; default 1024)
minprocs=655350; (min. avail process descriptors; default 200)
;umask=022 ; (process file creation umask;default 022)
;user=admin ; (default is current user, required if root)
;identifier=supervisor ; (supervisord identifier, default is 'supervisor')
;directory=/tmp ; (default is not to cd during start)
;nocleanup=true ; (don't clean up tempfiles at start;default false)
;childlogdir=/tmp ; ('AUTO' child log dir, default $TEMP)
;environment=KEY="value" ; (key value pairs to add to environment)
;strip_ansi=false ; (strip ansi escape codes in logs; def. false)

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix://{<!-- -->{ taishi_dir }}/tmp/supervisor.sock ; use a unix:// URL for a unix socket

[include]
files={<!-- -->{ taishi_dir }}/etc/supervisord/*.ini

templates/supervisord.conf.j2

#!/bin/bash


#/usr/bin/supervisord -c __install_dir__/etc/supervisord.conf
# dpkg-reconfigure dash
/usr/bin/supervisord -c {<!-- -->{ taishi_dir }}/etc/supervisord.conf 

templates/start_taishi.sh.j2

# taishi enterprise supervisord service for systemd (CentOS 7.0 + )
[Unit]
Description=taishi Enterprise Supervisor daemon
After=taishi.service

[Service]
Type=forking
LimitNOFILE=655350
LimitNPROC=655350
ExecStart=/bin/bash {<!-- -->{ taishi_dir }}/etc/start_taishi.sh
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=no
TimeoutSec=1200s

[Install]
WantedBy=multi-user.target

templates/taishi.service.j2

Automatically install and configure supervisor on all nodes and start successfully

ansible installs cesi and registers it as a background service

Flask==1.0.2
Flask-SQLAlchemy==2.3.2
tomlkit==0.5.3

files/requirements.txt

[cesi]
# Database Uri
database = "sqlite:///users.db" # Relative path
#Etc
#database = "sqlite:opt/cesi/< version >/users.db" # Absolute path
#database = "postgres://<user>:<password>@localhost:5432/<database_name>"
#database = "mysql + pymysql://<user>:<password>@localhost:3306/<database_name>"
activity_log = "activity.log" # File path for CeSI logs
admin_username = "admin" # Username of admin user
admin_password = "admin" # Password of admin user

# This is the definition section for new supervisord node.
# [[nodes]]
# name = "api" # (String) Unique name for supervisord node.
# environment = "" # (String) The environment name provides logical grouping of supervisord nodes. It can be used as filtering option in the UI.
# username = "" # (String) Username of the XML-RPC interface of supervisord Set nothing if no username is configured
# password = "" # (String) Password of the XML-RPC interface of supervisord. Set nothing if no username is configured
# host = "127.0.0.1" # (String) Host of the XML-RPC interface of supervisord
# port = "9001" # (String) Port of the XML-RPC interface of supervisord

# Default supervisord nodes
[[nodes]]
name = "192.168.30.174"
environment = ""
username = ""
password = ""
host = "192.168.30.174"
port = "9001"

[[nodes]]
name = "192.168.30.175"
environment = ""
username = ""
password = ""
host = "192.168.30.175"
port = "9001"


[[nodes]]
name = "192.168.30.176"
environment = ""
username = ""
password = ""
host = "192.168.30.176"
port = "9001"

templates/cesi.conf.toml.j2

[Unit]
Description=cesi

[Service]
Environment=
ExecStart=/usr/local/python3.9/bin/python3 {<!-- -->{taishi_dir}}/cesi/cesi/run.py --config-file {<!-- -->{ taishi_dir } }/cesi/defaults/cesi.conf.toml
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=TERM
User=root
WorkingDirectory={<!-- -->{taishi_dir}}/cesi
Restart=on-failure

[Install]
WantedBy=multi-user.target

templates/cesi.service.j2

- name: Create cesi dir
  file: path="{<!-- -->{ taishi_dir }}/cesi" state=directory owner={<!-- -->{ taishi_user }} group={<!-- -->{ taishi_user } } recurse=yes
  tags: cesi

- name: Copy cesi.tar to {<!-- -->{groups["cesi"]}}
  copy: src=cesi.tar.gz dest=/tmp
  tags: cesi


- name: "Install cesi for {<!-- -->{groups['cesi']}}"
  unarchive: src="/tmp/cesi.tar.gz" dest="{<!-- -->{ taishi_dir }}/cesi" copy=no mode=0755 owner={<!-- -->{ taishi_user }} group={<!-- -->{ taishi_user }}
  tags: cesi

- name: "copy python3.9 for {<!-- -->{groups['cesi']}}"
  copy: src=Python-3.9.0.tgz dest=/tmp mode=0755 owner={<!-- -->{ taishi_user }} group={<!-- -->{ taishi_user }}
  tags: cesi

- name: "Install python3.9 for {<!-- -->{groups['cesi']}}"
  unarchive: src="/tmp/Python-3.9.0.tgz" dest="{<!-- -->{ taishi_dir }}/cesi" copy=no mode=0755 owner={<!-- --> { taishi_user }} group={<!-- -->{ taishi_user }}
  tags: cesi

- name: "make python3.9 for {<!-- -->{groups['cesi']}}"
  shell: "yum install -y zlib zlib-devel openssl openssl-devel libffi-devel sqlite-devel & amp; & amp; rm -fr /usr/local/python3.9 & amp; & amp; mkdir /usr/local/ python3.9 & amp; & amp; cd {<!-- -->{ taishi_dir }}/cesi/Python-3.9.0 & amp; & amp; ./configure --prefix=/usr/local/python3. 9 & amp; & amp; make & amp; & amp; make install"
  ignore_errors: True
  tags: cesi

- name: "copy requirements for {<!-- -->{groups['cesi']}}"
  copy: src=requirements.txt dest={<!-- -->{ taishi_dir }}/cesi/requirements.txt mode=0755 owner={<!-- -->{ taishi_user }} group={<!- - -->{taishi_user }}
  tags: cesi

- name: "Install python3 requirements"
  shell: "/usr/local/python3.9/bin/python3.9 -m pip install --upgrade pip & amp; & amp; cd {<!-- -->{ taishi_dir }}/cesi/ & amp; & amp; /usr/local/python3.9/bin/pip3 install -r requirements.txt & amp; & amp; /usr/local/python3.9/bin/pip3 install --upgrade sqlalchemy==1.3.23"
  ignore_errors: True
  tags: cesi

- name: "Copy the cesi.conf"
  template: src=cesi.conf.toml.j2 dest="{<!-- -->{ taishi_dir }}/cesi/defaults/cesi.conf.toml" owner={<!-- -->{ taishi_user } } group={<!-- -->{ taishi_user }} mode=0755
  tags: cesi

- name: "Copy the cesi service"
  template: src=cesi.service.j2 dest="/etc/systemd/system/cesi.service" owner={<!-- -->{ taishi_user }} group={<!-- -->{ taishi_user } } mode=0755
  tags: cesi

- name: reload cesiservice to {<!-- -->{ groups["cesi"] }}
  shell: "systemctl daemon-reload"
  tags: cesi

- name: start cesiservice to {<!-- -->{ groups["cesi"] }}
  service: name=cesi state=started
  tags: cesi

tasks/main.yml

Automatically start the service after installation is complete