From b8ff753e62cda46c195acbce0ce0f9450b18e941 Mon Sep 17 00:00:00 2001 From: gongzt Date: Wed, 18 Oct 2023 15:57:34 +0800 Subject: [PATCH 1/3] It is suitable for version 20.03-LTS-sp3 --- 0003-update-aops-basedatabase.patch | 29 ++++ 0004-fix-information-path-incorrect.patch | 55 ++++++ 0005-suitable-for-version-2003-sp3.patch | 196 ++++++++++++++++++++++ aops-vulcanus.spec | 12 +- 4 files changed, 289 insertions(+), 3 deletions(-) create mode 100644 0003-update-aops-basedatabase.patch create mode 100644 0004-fix-information-path-incorrect.patch create mode 100644 0005-suitable-for-version-2003-sp3.patch diff --git a/0003-update-aops-basedatabase.patch b/0003-update-aops-basedatabase.patch new file mode 100644 index 0000000..bfd1350 --- /dev/null +++ b/0003-update-aops-basedatabase.patch @@ -0,0 +1,29 @@ +From 5cb95dafa699058cbdfb3056e8b10960f2a82408 Mon Sep 17 00:00:00 2001 +From: smjiao +Date: Mon, 9 Oct 2023 07:13:16 +0000 +Subject: update scripts/deploy/aops-basedatabase.sh +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: smjiao +--- + scripts/deploy/aops-basedatabase.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/deploy/aops-basedatabase.sh b/scripts/deploy/aops-basedatabase.sh +index 49a80f4..438716d 100755 +--- a/scripts/deploy/aops-basedatabase.sh ++++ b/scripts/deploy/aops-basedatabase.sh +@@ -1,7 +1,7 @@ + #!/bin/bash + . /usr/bin/aops-vulcanus + REPO_CONFIG_FILE="/etc/yum.repos.d/aops_elascticsearch.repo" +-INSTALL_SOFTWARE=$1 ++INSTALL_SOFTWARE=$2 + + function check_es_status() { + visit_es_response=$(curl -s -XGET http://127.0.0.1:9200) +-- +Gitee + diff --git a/0004-fix-information-path-incorrect.patch b/0004-fix-information-path-incorrect.patch new file mode 100644 index 0000000..1593ebe --- /dev/null +++ b/0004-fix-information-path-incorrect.patch @@ -0,0 +1,55 @@ +From 565c3e1263fd5835c17309cc92d84e31f893abfb Mon Sep 17 00:00:00 2001 +From: zhangdaolong +Date: Thu, 12 Oct 2023 17:34:12 +0800 +Subject: The information path is incorrect +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--- + aops-vulcanus | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/aops-vulcanus b/aops-vulcanus +index f00b4a0..c0fc779 100644 +--- a/aops-vulcanus ++++ b/aops-vulcanus +@@ -100,7 +100,7 @@ function is_started() { + function start_service() { + module_name=$1 + echo "[INFO] 1. Before starting the service, ensure that the data table is initialized" +- echo "[INFO] 2. Execute aops-basedatabase zeus or apollo to complete the data table initialization, For example '/opt/aops/script/aops-basedatabase init zeus'" ++ echo "[INFO] 2. Execute aops-basedatabase zeus or apollo to complete the data table initialization, For example '/opt/aops/scripts/deploy/aops-basedatabase.sh init zeus'" + rm -rf ${OUT_PATH}/"${module_name}".pid + uwsgi -d --ini ${OUT_PATH}/"${module_name}".ini --enable-threads + pid=`ps auxww | grep $module_name.ini | grep -v grep | awk '{print $2}'` +@@ -140,7 +140,7 @@ function check_es_installed() { + if [ -z "${es_ip}" ] || [ -z "${es_port}" ]; then + echo "[ERROR] can not find config name 'ip' or 'port' of elasticsearch in: ${CONFIG_FILE}, please check the file" + echo "If you have installed ES, Please set correct 'ip' value and 'port' of elasticsearch value and re-execute '${DATABASE_CONSTANT} start' " +- echo "If you have not installed ES, please execute the automatic installation script '/opt/aops/script/aops-basedatabase elasticsearch' under the root user " ++ echo "If you have not installed ES, please execute the automatic installation script '/opt/aops/scripts/deploy/aops-basedatabase.sh elasticsearch' under the root user " + exit 1 + fi + check_num "${es_port}" "es_port" +@@ -149,7 +149,7 @@ function check_es_installed() { + if [ -z "${visit_es_response}" ]; then + echo "=========================================================================" + echo "[ERROR] elasticsearch connection FAILED,the following reason may cause failed:" +- echo "[INFO] 1. You have not installed Elasticsearch, if you need to install, please execute the automatic installation script '/opt/aops/script/sops-basedatabase' under the root user" ++ echo "[INFO] 1. You have not installed Elasticsearch, if you need to install, please execute the automatic installation script '/opt/aops/scripts/deploy/aops-basedatabase.sh' under the root user" + echo "[INFO] 2. Elasticsearch configuration is incorrect, please update value of 'ip' and 'port' of elasticsearch in $CONFIG_FILE" + echo "[INFO] 3. Elasticsearch service not started, please start elasticsearch service." + exit 1 +@@ -184,7 +184,7 @@ except pymysql.err.OperationalError: + if [ "${init_result}" = "False" ]; then + echo "=========================================================================" + echo "[ERROR] mysql connection FAILED, the following reason may cause failed:" +- echo "[INFO] 1. You have not installed mysql,If you need to install, please execute the automatic installation script '/opt/aops/script/aops-basedatabase' under the root user, For example '/opt/aops/script/aops-basedatabase install mysql'" ++ echo "[INFO] 1. You have not installed mysql,If you need to install, please execute the automatic installation script '/opt/aops/scripts/deploy/aops-basedatabase.sh' under the root user, For example '/opt/aops/scripts/deploy/aops-basedatabase.sh install mysql'" + echo "[INFO] 2. mysql configuration is incorrect,please update value of 'ip' and 'port' of mysql in ${CONFIG_FILE}" + echo "[INFO] 3. mysql service not started,please start mysql service." + exit 1 +-- +Gitee + diff --git a/0005-suitable-for-version-2003-sp3.patch b/0005-suitable-for-version-2003-sp3.patch new file mode 100644 index 0000000..2eb01b9 --- /dev/null +++ b/0005-suitable-for-version-2003-sp3.patch @@ -0,0 +1,196 @@ +From 91490e80fe9c6deb16042a2919f3c916ce274e1e Mon Sep 17 00:00:00 2001 +From: gongzt +Date: Mon, 16 Oct 2023 11:08:12 +0800 +Subject: It is suitable for version 20.03-LTS-sp3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--- + aops-vulcanus | 33 +------------------------ + aops-vulcanus.spec | 2 +- + scripts/deploy/aops-basedatabase.sh | 38 ++++++++++++++++++++++++++++- + scripts/deploy/container/run.sh | 11 ++++++--- + 4 files changed, 46 insertions(+), 38 deletions(-) + +diff --git a/aops-vulcanus b/aops-vulcanus +index f00b4a0..cef2b4f 100644 +--- a/aops-vulcanus ++++ b/aops-vulcanus +@@ -192,36 +192,5 @@ except pymysql.err.OperationalError: + echo "[INFO] mysql check ok" + } + +-function init_database_and_table() { +- CONFIG_FILE=$1 +- mysql_ip=$(get_config "${CONFIG_FILE}" "mysql" "ip") +- port=$(get_config "${CONFIG_FILE}" "mysql" "port") +- sql_file=$2 +- init_database_and_table_cmd="import pymysql,os +-try: +- database = pymysql.connect(host='$mysql_ip', port=$port, database='mysql', autocommit=True) +- with open('$sql_file', 'r', encoding='utf-8') as file: +- sql = file.read() +- if not sql: +- print(False) +- else: +- cursor = database.cursor() +- for command in filter(lambda _sql: _sql != os.linesep and _sql, sql.split(';')): +- sql_command = command.replace(os.linesep, '') +- if not sql_command: +- continue +- cursor.execute(sql_command) +- database.close() +-except (IOError, pymysql.err.OperationalError): +- print(False) +-" +- init_result=$(python3 -c "$init_database_and_table_cmd") +- if [ "${init_result}" = "False" ]; then +- echo "[ERROR] Table initialization failed" +- echo "[INFO] 1. Make sure that the data table initialization of the zeus service is performed first." +- echo "[INFO] 2. Check that the database configuration file is correct, please check value of 'ip' and 'port' of mysql in ${CONFIG_FILE}" +- else +- echo "[INFO] Database and table initialization ok" +- fi +-} ++ + +diff --git a/aops-vulcanus.spec b/aops-vulcanus.spec +index bf802e3..e5c4d86 100644 +--- a/aops-vulcanus.spec ++++ b/aops-vulcanus.spec +@@ -14,7 +14,7 @@ Requires: python3-concurrent-log-handler python3-xmltodict python3-pyyaml pyth + Requires: python3-requests python3-xlrd python3-prettytable python3-pygments python3-sqlalchemy + Requires: python3-elasticsearch >= 7 python3-prometheus-api-client python3-urllib3 python3-werkzeug + Requires: python3-flask python3-flask-restful python3-PyMySQL python3-kafka-python +-Requires: python-jwt python-redis python3-Flask-APScheduler >= 1.11.0 python3-APScheduler ++Requires: python-jwt python3-redis python3-Flask-APScheduler >= 1.11.0 python3-APScheduler + Provides: aops-vulcanus + Conflicts: aops-utils + +diff --git a/scripts/deploy/aops-basedatabase.sh b/scripts/deploy/aops-basedatabase.sh +index 438716d..a8f5898 100755 +--- a/scripts/deploy/aops-basedatabase.sh ++++ b/scripts/deploy/aops-basedatabase.sh +@@ -1,5 +1,4 @@ + #!/bin/bash +-. /usr/bin/aops-vulcanus + REPO_CONFIG_FILE="/etc/yum.repos.d/aops_elascticsearch.repo" + INSTALL_SOFTWARE=$2 + +@@ -128,6 +127,43 @@ function install_database() { + fi + } + ++function get_config() { ++ INIFILE=$1 ++ SECTION=$2 ++ ITEM=$3 ++ awk -F '=' '/\['"$SECTION"'\]/{a=1}a==1&&$1~/'"$ITEM"'/{print $2; exit}' "$INIFILE" ++} ++ ++function init_database_and_table() { ++ CONFIG_FILE=$1 ++ mysql_ip=$(get_config "${CONFIG_FILE}" "mysql" "ip") ++ port=$(get_config "${CONFIG_FILE}" "mysql" "port") ++ sql_file=$2 ++ init_database_and_table_cmd="import pymysql,os ++from pymysql.constants import CLIENT ++try: ++ database = pymysql.connect(host='$mysql_ip', port=$port, database='mysql', autocommit=True,client_flag=CLIENT.MULTI_STATEMENTS) ++ with open('$sql_file', 'r', encoding='utf-8') as file: ++ sql = file.read() ++ if not sql: ++ print(False) ++ else: ++ cursor = database.cursor() ++ cursor.execute(sql) ++ database.close() ++except (IOError, pymysql.err.OperationalError): ++ print(False) ++" ++ init_result=$(python3 -c "$init_database_and_table_cmd") ++ if [ "${init_result}" = "False" ]; then ++ echo "[ERROR] Table initialization failed" ++ echo "[INFO] 1. Make sure that the data table initialization of the zeus service is performed first." ++ echo "[INFO] 2. Check that the database configuration file is correct, please check value of 'ip' and 'port' of mysql in ${CONFIG_FILE}" ++ else ++ echo "[INFO] Database and table initialization ok" ++ fi ++} ++ + function main(){ + operation=$1 + service=$2 +diff --git a/scripts/deploy/container/run.sh b/scripts/deploy/container/run.sh +index 581c0bc..dffbfaf 100755 +--- a/scripts/deploy/container/run.sh ++++ b/scripts/deploy/container/run.sh +@@ -71,11 +71,12 @@ main(){ + while : + do + echo "===========================Container arrangement===========================" +- echo "1. Build the docker container (build)." +- echo "2. Start the container orchestration service (start-service/start-env)." +- echo "3. Stop all container services (stop-service/stop-env)." ++ echo "Welcome to the one-click deployment script, supporting pre-building of container images and start-stop of services." ++ echo "Image Building (build): supports the generation of docker images for zeus, apollo, hermes services." ++ echo "Service Start (start): the service types are divided into basic environment services and application services. Basic environment services include mysql, elasticsearch, redis, kafka, prometheus, which can be started by entering the 'start-env' option. Application services include apollo, zeus, hermes, which can be started by entering the 'start-service' option. please remember that, in the absence of a pre-existing environment, the correct order of using one-click startup services is to first execute "start-env" and then "start-service" Both steps are essential and cannot be skipped." ++ echo "Stop Service (stop): enter 'stop-env' or 'stop-service' to stop the basic environment services and application services respectively. After the basic environment services are stopped, if the configuration items of the application services are not reconfigured, it will cause the application services to be unusable. Conversely, after stopping the application services, there is no impact on the basic environment services." + echo "Enter to exit the operation (Q/q)." +- read -p "Select an operation procedure to continue: " operation ++ read -p "Please enter build, start-env, start-service, stop-env, stop-service, or q/Q to proceed to the next step: " operation + case $operation in + "build") + docker_build +@@ -83,6 +84,8 @@ main(){ + ;; + "start-service") + docker-compose up -d ++ bash /opt/aops/scripts/aops-basedatabase.sh init zeus ++ bash /opt/aops/scripts/aops-basedatabase.sh init apollo + ;; + "start-env") + prometheus +-- +Gitee + + +From adf7afd90a882e013e0d16a7e1af35572d75f38f Mon Sep 17 00:00:00 2001 +From: gongzt +Date: Wed, 18 Oct 2023 14:11:59 +0800 +Subject: [PATCH 2/2] =?UTF-8?q?=E9=80=82=E9=85=8D20.03-sp3=E7=89=88?= + =?UTF-8?q?=E6=9C=AC=E4=B8=AD=E7=9A=84python-jwt?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--- + vulcanus/token.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/vulcanus/token.py b/vulcanus/token.py +index e449991..786d5f3 100644 +--- a/vulcanus/token.py ++++ b/vulcanus/token.py +@@ -60,12 +60,16 @@ def generate_token(unique_iden, minutes=20, **kwargs): + try: + token_body["key"] = unique_iden + token_body["create_time"] = time.localtime() +- return jwt.encode( ++ jwt_token = jwt.encode( + token_body, + configuration.individuation.get("PRIVATE_KEY"), + algorithm="HS256", + headers=dict(alg="HS256"), + ) ++ if isinstance(jwt_token, bytes): ++ jwt_token = jwt_token.decode("utf-8") ++ return jwt_token ++ + except Exception: + raise ValueError("Token generation failed") + +-- +Gitee + diff --git a/aops-vulcanus.spec b/aops-vulcanus.spec index b73fb9d..feca2d2 100644 --- a/aops-vulcanus.spec +++ b/aops-vulcanus.spec @@ -1,20 +1,23 @@ Name: aops-vulcanus Version: v1.3.0 -Release: 3 +Release: 4 Summary: A basic tool libraries of aops, including logging, configure and response, etc. License: MulanPSL2 URL: https://gitee.com/openeuler/%{name} Source0: %{name}-%{version}.tar.gz Patch0001: 0001-optimize-service-start-check-logic.patch Patch0002: 0002-fix-systemctl-startup-service-error.patch +Patch0003: 0003-update-aops-basedatabase.patch +Patch0004: 0004-fix-information-path-incorrect.patch +Patch0005: 0005-suitable-for-version-2003-sp3.patch BuildRequires: python3-setuptools Requires: python3-concurrent-log-handler python3-xmltodict python3-pyyaml python3-marshmallow >= 3.13.0 Requires: python3-requests python3-xlrd python3-prettytable python3-pygments python3-sqlalchemy -Requires: python3-elasticsearch >= 7 python3-prometheus-api-client python3-urllib3 python3-werkzeug +Requires: python3-elasticsearch >= 7 python3-urllib3 python3-werkzeug Requires: python3-flask python3-flask-restful python3-PyMySQL python3-kafka-python -Requires: python-jwt python-redis +Requires: python-jwt python3-redis Provides: aops-vulcanus Conflicts: aops-utils @@ -62,6 +65,9 @@ cp -r scripts %{buildroot}/opt/aops/ %changelog +* Wed Oct 18 2023 gongzhengtang - v1.3.0-4 +- it is suitable for version 20.03-LTS-sp3 + * Tue Sep 19 2023 wenxin - v1.3.0-3 - fix systemctl startup service problem -- Gitee From 731461b6efdbbfe9cc6a1828c40ad9c575192ea5 Mon Sep 17 00:00:00 2001 From: gongzt Date: Wed, 18 Oct 2023 17:12:52 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dspec=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=B8=ADpython3-prometheus-api-client=E7=9A=84=E4=BE=9D?= =?UTF-8?q?=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aops-vulcanus.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aops-vulcanus.spec b/aops-vulcanus.spec index feca2d2..118f82b 100644 --- a/aops-vulcanus.spec +++ b/aops-vulcanus.spec @@ -15,7 +15,7 @@ Patch0005: 0005-suitable-for-version-2003-sp3.patch BuildRequires: python3-setuptools Requires: python3-concurrent-log-handler python3-xmltodict python3-pyyaml python3-marshmallow >= 3.13.0 Requires: python3-requests python3-xlrd python3-prettytable python3-pygments python3-sqlalchemy -Requires: python3-elasticsearch >= 7 python3-urllib3 python3-werkzeug +Requires: python3-elasticsearch >= 7 python3-prometheus-api-client python3-urllib3 python3-werkzeug Requires: python3-flask python3-flask-restful python3-PyMySQL python3-kafka-python Requires: python-jwt python3-redis Provides: aops-vulcanus -- Gitee From f6ed870d956d8e79af4d1dee1208d823b818c0c3 Mon Sep 17 00:00:00 2001 From: gongzt Date: Wed, 18 Oct 2023 17:25:45 +0800 Subject: [PATCH 3/3] fix python3-prometheus-api-client import error --- ...3-prometheus-api-client-import-error.patch | 134 ++++++++++++++++++ aops-vulcanus.spec | 3 +- 2 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 0006-fix-python3-prometheus-api-client-import-error.patch diff --git a/0006-fix-python3-prometheus-api-client-import-error.patch b/0006-fix-python3-prometheus-api-client-import-error.patch new file mode 100644 index 0000000..a903d07 --- /dev/null +++ b/0006-fix-python3-prometheus-api-client-import-error.patch @@ -0,0 +1,134 @@ +From 53cbfd342bcc39a98f0be257a70fefde3fe404eb Mon Sep 17 00:00:00 2001 +From: gongzt +Date: Wed, 18 Oct 2023 17:22:26 +0800 +Subject: fix python3-prometheus-api-client import error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--- + vulcanus/database/proxy.py | 101 ------------------------------------- + 1 file changed, 101 deletions(-) + +diff --git a/vulcanus/database/proxy.py b/vulcanus/database/proxy.py +index 94e9883..c1ff0fe 100644 +--- a/vulcanus/database/proxy.py ++++ b/vulcanus/database/proxy.py +@@ -24,7 +24,6 @@ import sqlalchemy + from sqlalchemy.exc import SQLAlchemyError, DisconnectionError + from sqlalchemy.orm import sessionmaker + from elasticsearch import Elasticsearch, ElasticsearchException, helpers, TransportError, NotFoundError +-from prometheus_api_client import PrometheusConnect, PrometheusApiClientException + import redis + from redis import Redis, ConnectionPool + from vulcanus.log.log import LOGGER +@@ -516,106 +515,6 @@ class ElasticsearchProxy(DataBaseProxy): + return query_body + + +-class PromDbProxy(DataBaseProxy): +- """ +- Proxy of prometheus time series database +- """ +- +- def __init__(self, host=None, port=None): +- """ +- Init Prometheus time series database proxy +- +- Args: +- host (str) +- port (int) +- """ +- self._host = host or configuration.prometheus.get('IP') +- self._port = port or configuration.prometheus.get('PORT') +- self._prom = PrometheusConnect(url="http://%s:%s" % (self._host, self._port), disable_ssl=True) +- if not self.connected: +- raise DatabaseConnectionFailed("Promethus connection failed.") +- +- @property +- def connected(self): +- """ +- Make a connect to database connection pool +- +- Returns: +- bool: connect succeed or fail +- """ +- +- return self._prom.check_prometheus_connection() +- +- def query(self, host, time_range, metric, label_config=None): +- """ +- query a metric's data of a host during a time range +- Args: +- host (str): host ip +- time_range (list): list of datetime.datetime +- metric (str): data type of prometheus +- label_config (dict): label config of metric +- +- Returns: +- tuple: (bool, dict) +- """ +- start_time = datetime.fromtimestamp(time_range[0]) +- end_time = datetime.fromtimestamp(time_range[1]) +- +- # metric of a host's all exporters +- # e.g. metric "up" of localhost: up{instance=127.0.0.1\\d{1,5}} +- host_condition = 'instance=~"%s:\\\\d{1,5}"' % host +- combined_condition = PromDbProxy._combine_condition(label_config, host_condition) +- +- metric_with_condition = metric + combined_condition +- +- try: +- data = self._prom.get_metric_range_data( +- metric_name=metric_with_condition, +- start_time=start_time, +- end_time=end_time, +- ) +- +- if not data: +- LOGGER.warning( +- "Query result is empty. Exporter of host %s doesn't record the " "metric '%s' during [%s, %s].", +- host, +- metric, +- start_time, +- end_time, +- ) +- +- return True, data +- +- except (ValueError, TypeError, PrometheusApiClientException) as error: +- LOGGER.error("Prometheus query failed. %s", error) +- failed_item = { +- "host_id": host, +- "name": metric, +- "label": label_config, +- } +- return False, [failed_item] +- +- @staticmethod +- def _combine_condition(label_config, *args): +- """ +- Combine condition together +- Args: +- label_config: label config of metric +- *args (str/list): one or multiple string of condition +- +- Returns: +- str +- """ +- condition_list = list(args) +- +- if label_config: +- for key, value in label_config.items(): +- condition_list.append(str(key) + "=" + '"' + value + '"') +- +- combined_condition = "{" + ",".join(condition_list) + "}" +- return combined_condition +- +- + @singleton + class RedisProxy(DataBaseProxy): + """ +-- +2.33.0 + diff --git a/aops-vulcanus.spec b/aops-vulcanus.spec index 118f82b..490da10 100644 --- a/aops-vulcanus.spec +++ b/aops-vulcanus.spec @@ -10,12 +10,13 @@ Patch0002: 0002-fix-systemctl-startup-service-error.patch Patch0003: 0003-update-aops-basedatabase.patch Patch0004: 0004-fix-information-path-incorrect.patch Patch0005: 0005-suitable-for-version-2003-sp3.patch +Patch0006: 0006-fix-python3-prometheus-api-client-import-error.patch BuildRequires: python3-setuptools Requires: python3-concurrent-log-handler python3-xmltodict python3-pyyaml python3-marshmallow >= 3.13.0 Requires: python3-requests python3-xlrd python3-prettytable python3-pygments python3-sqlalchemy -Requires: python3-elasticsearch >= 7 python3-prometheus-api-client python3-urllib3 python3-werkzeug +Requires: python3-elasticsearch >= 7 python3-urllib3 python3-werkzeug Requires: python3-flask python3-flask-restful python3-PyMySQL python3-kafka-python Requires: python-jwt python3-redis Provides: aops-vulcanus -- Gitee