From 219942b85d7e2462fd7ef67f27c3946f58eca04b Mon Sep 17 00:00:00 2001 From: mabofu Date: Wed, 12 Apr 2023 10:39:22 +0800 Subject: [PATCH] Add a program dsms-deploy to install the cluster --- .gitignore | 281 +++++++ dsms_deploy/Makefile | 39 + dsms_deploy/config/add-node.conf | 27 + dsms_deploy/config/cluster.conf | 70 ++ dsms_deploy/config/depend_list | 80 ++ dsms_deploy/config/dsms-deploy.spec | 42 + .../config/whl/ceph-deploy-2.0.1.tar.gz | Bin 0 -> 121248 bytes dsms_deploy/dsms-deploy.py | 784 ++++++++++++++++++ 8 files changed, 1323 insertions(+) create mode 100644 .gitignore create mode 100644 dsms_deploy/Makefile create mode 100644 dsms_deploy/config/add-node.conf create mode 100644 dsms_deploy/config/cluster.conf create mode 100644 dsms_deploy/config/depend_list create mode 100644 dsms_deploy/config/dsms-deploy.spec create mode 100644 dsms_deploy/config/whl/ceph-deploy-2.0.1.tar.gz create mode 100755 dsms_deploy/dsms-deploy.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7850886 --- /dev/null +++ b/.gitignore @@ -0,0 +1,281 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +.idea + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +.idea \ No newline at end of file diff --git a/dsms_deploy/Makefile b/dsms_deploy/Makefile new file mode 100644 index 0000000..be8609f --- /dev/null +++ b/dsms_deploy/Makefile @@ -0,0 +1,39 @@ +RPM_NAME=dsms-deploy +RPM_VERSION=1.1 +RPM_RELEASE=2.0.0 +RPM_ARCH=x86_64 +RPM_BUILD_DIR=$(shell pwd)/rpmbuild +RPM_SPEC_FILE=$(RPM_BUILD_DIR)/SPECS/$(RPM_NAME).spec + +.PHONY: clean build + +clean: + rm -rf target + rm -rf dist + rm -rf $(RPM_BUILD_DIR) +build: clean + mkdir -p $(RPM_BUILD_DIR)/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} + mkdir -p $(RPM_BUILD_DIR)/BUILD/$(RPM_NAME)/ + pyinstaller --onefile dsms-deploy.py + cp dist/dsms-deploy $(RPM_BUILD_DIR)/BUILD/$(RPM_NAME)/ + cp config/cluster.conf $(RPM_BUILD_DIR)/BUILD/$(RPM_NAME)/ + cp config/add-node.conf $(RPM_BUILD_DIR)/BUILD/$(RPM_NAME)/ + cp config/depend_list $(RPM_BUILD_DIR)/BUILD/$(RPM_NAME)/ + cp config/whl/* $(RPM_BUILD_DIR)/BUILD/$(RPM_NAME)/ + + sed -e "s/@RPM_NAME@/$(RPM_NAME)/g" \ + -e "s/@RPM_VERSION@/$(RPM_VERSION)/g" \ + -e "s/@RPM_RELEASE@/$(RPM_RELEASE)/g" \ + -e "s/@RPM_ARCH@/$(RPM_ARCH)/g" \ + -e "s|@RPM_BUILD_DIR@|$(RPM_BUILD_DIR)|g" \ + config/$(RPM_NAME).spec > $(RPM_SPEC_FILE) + + rpmbuild -bb $(RPM_SPEC_FILE) + + mkdir target + + find $(RPM_BUILD_DIR)/RPMS -type f -name "*.rpm" -exec cp {} ./target \; + + rm -rf $(RPM_BUILD_DIR) + + rm -rf dist \ No newline at end of file diff --git a/dsms_deploy/config/add-node.conf b/dsms_deploy/config/add-node.conf new file mode 100644 index 0000000..7579c70 --- /dev/null +++ b/dsms_deploy/config/add-node.conf @@ -0,0 +1,27 @@ +#Configuration file of new node in existing cluster + +#NEW_NODE1 +#cluster new node ip +#Requries Configuration +NEW_NODE1_IP= +#cluster new node hostname +#Requries Configuration +NEW_NODE1_HOSTNAME= +#cluster new node ssh port +#Requries Configuration +NEW_NODE1_SSH_PORT=22 +#cluster new node root password +#Requries Configuration +NEW_NODE1_ROOT_PASSWD= +#A daemon that maintains a map of the state of the cluster. +#Requries Configuration +NEW_NODE1_MON=yes + + +#Customize yum repository public key file +#support local gpg key file path or remote http gpg key file url +#Optional Configuration +REPO_KEY_FILE= +#Customize yum repository URL +#Optional Configuration +REPO_URL= \ No newline at end of file diff --git a/dsms_deploy/config/cluster.conf b/dsms_deploy/config/cluster.conf new file mode 100644 index 0000000..9f1d8c7 --- /dev/null +++ b/dsms_deploy/config/cluster.conf @@ -0,0 +1,70 @@ +#Deploy the config file for the new cluster + +#NODE1 +#cluster node ip,dsms-deploy use ssh to connect +#require config +NODE1_IP= +#cluster node hostname,dsms-deploy will change the node hostname +#require config +NODE1_HOSTNAME= +#cluster node ssh port +#require config +NODE1_SSH_PORT=22 +#cluster node root password +#require config +NODE1_ROOT_PASSWD= +#A daemon that maintains a map of the state of the cluster. +#require config +NODE1_MON=yes + +#NODE2 +#cluster node ip,dsms-deploy use ssh to connect +#require config +NODE2_IP= +#cluster node hostname,dsms-deploy will change the node hostname +#require config +NODE2_HOSTNAME= +#cluster node ssh port +#require config +NODE2_SSH_PORT=22 +#cluster node root password +#require config +NODE2_ROOT_PASSWD= +#A daemon that maintains a map of the state of the cluster. +#require config +NODE2_MON=yes + + +#NODE3 +#cluster node ip,dsms-deploy use ssh to connect +#require config +NODE3_IP= +#cluster node hostname,dsms-deploy will change the node hostname +#require config +NODE3_HOSTNAME= +#cluster node ssh port +#require config +NODE3_SSH_PORT=22 +#cluster node root password +#require config +NODE3_ROOT_PASSWD= +#A daemon that maintains a map of the state of the cluster. +#require config +NODE3_MON=yes + +#CLUSTER NETWORK CONFIG +#use CIDR notation for subnets (e.g., 10.0.0.0/24). +#clusters front-side public network for access service +#require config +PUBLIC_NETWORK= +#cluster back side cluster network for osd object replication,heart beats,backfilling,recovery,etc. +#require config +CLUSTER_NETWORK= + +#Customize yum repository public key file +#support local gpg key file path or remote http gpg key file url +#Optional config +REPO_KEY_FILE= +#Customize yum repository URL +#Optional config +REPO_URL= \ No newline at end of file diff --git a/dsms_deploy/config/depend_list b/dsms_deploy/config/depend_list new file mode 100644 index 0000000..1778da1 --- /dev/null +++ b/dsms_deploy/config/depend_list @@ -0,0 +1,80 @@ +depend=abseil-cpp-20200923.3-1.el8.x86_64.rpm +depend=gperftools-libs-2.7-9.el8.x86_64.rpm +depend=grpc-data-1.34.1-8.0.1.an8.noarch.rpm +depend=leveldb-1.22-1.el8.x86_64.rpm +depend=leveldb-devel-1.22-1.el8.x86_64.rpm +depend=liboath-2.6.2-3.el8.x86_64.rpm +depend=libunwind-1.3.1-3.el8.x86_64.rpm +depend=platform-python-devel-3.6.8-45.0.1.an8.x86_64.rpm +depend=protobuf-3.14.0-6.an8.x86_64.rpm +depend=python3-apipkg-1.5-6.el8.noarch.rpm +depend=python3-beautifulsoup4-4.6.3-2.el8.1.noarch.rpm +depend=python3-bcrypt-3.1.6-2.el8.1.x86_64.rpm +depend=python3-cheroot-8.5.2-1.el8.noarch.rpm +depend=python3-cherrypy-18.4.0-1.el8.noarch.rpm +depend=python3-execnet-1.7.1-1.el8.noarch.rpm +depend=python3-grpcio-1.34.1-8.0.1.an8.x86_64.rpm +depend=python3-jaraco-6.2-6.el8.noarch.rpm +depend=python3-jaraco-functools-2.0-4.el8.noarch.rpm +depend=python3-logutils-0.3.5-11.el8.noarch.rpm +depend=python3-more-itertools-7.2.0-3.el8.noarch.rpm +depend=python3-pecan-1.3.2-9.el8.noarch.rpm +depend=python3-portend-2.6-1.el8.noarch.rpm +depend=python3-remoto-1.2.1-1.el8.noarch.rpm +depend=python3-repoze-lru-0.7-6.el8.noarch.rpm +depend=python3-routes-2.4.1-12.el8.noarch.rpm +depend=python3-simplegeneric-0.8.1-17.el8.noarch.rpm +depend=python3-singledispatch-3.4.0.3-18.el8.noarch.rpm +depend=python3-tempora-1.14.1-5.el8.noarch.rpm +depend=python3-trustme-0.6.0-4.el8.noarch.rpm +depend=python3-waitress-1.2.1-2.el8.1.noarch.rpm +depend=python3-webob-1.8.5-1.el8.1.noarch.rpm +depend=python3-webtest-2.0.33-1.el8.noarch.rpm +depend=python3-zc-lockfile-2.0-2.el8.noarch.rpm +depend=re2-20190801-1.el8.x86_64.rpm +depend=resource-agents-4.9.0-35.el8.x86_64.rpm +whl=ceph-deploy-2.0.1.tar.gz +ceph_rpm=ceph-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=cephadm-2.0.0_anolis-0.an8.noarch.rpm +ceph_rpm=ceph-base-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=ceph-common-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=ceph-fuse-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=ceph-grafana-dashboards-2.0.0_anolis-0.an8.noarch.rpm +ceph_rpm=ceph-immutable-object-cache-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=ceph-mds-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=ceph-mgr-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=ceph-mgr-cephadm-2.0.0_anolis-0.an8.noarch.rpm +ceph_rpm=ceph-mgr-dashboard-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=ceph-mgr-diskprediction-cloud-2.0.0_anolis-0.an8.noarch.rpm +ceph_rpm=ceph-mgr-diskprediction-local-2.0.0_anolis-0.an8.noarch.rpm +ceph_rpm=ceph-mgr-modules-core-2.0.0_anolis-0.an8.noarch.rpm +ceph_rpm=ceph-mon-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=ceph-osd-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=ceph-prometheus-alerts-2.0.0_anolis-0.an8.noarch.rpm +ceph_rpm=ceph-radosgw-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=ceph-resource-agents-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=ceph-selinux-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=libcephfs2-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=libcephfs-devel-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=librados2-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=librados-devel-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=libradospp-devel-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=libradosstriper1-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=libradosstriper-devel-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=librbd1-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=librbd-devel-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=librgw2-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=librgw-devel-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=python3-ceph-argparse-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=python3-ceph-common-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=python3-cephfs-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=python3-rados-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=python3-rbd-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=python3-rgw-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=rados-objclass-devel-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=rbd-fuse-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=rbd-mirror-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=rbd-nbd-2.0.0_anolis-0.an8.x86_64.rpm +ceph_rpm=dsms-prometheus-2.32.1-2.el8.x86_64.rpm +ceph_rpm=dsms-prometheus-alertmanager-0.23.0-7.el8.x86_64.rpm +ceph_rpm=dsms-prometheus-node-exporter-1.3.1-4.el8.x86_64.rpm \ No newline at end of file diff --git a/dsms_deploy/config/dsms-deploy.spec b/dsms_deploy/config/dsms-deploy.spec new file mode 100644 index 0000000..88baa7f --- /dev/null +++ b/dsms_deploy/config/dsms-deploy.spec @@ -0,0 +1,42 @@ +%define _topdir @RPM_BUILD_DIR@ +%define name @RPM_NAME@ +%define version @RPM_VERSION@ +%define release @RPM_RELEASE@ +%define arch @RPM_ARCH@ + +Name: %{name} +Version: %{version} +Release: %{release} +Summary: DSMS STORAGE components, providing a distributed storage. +License: MIT +BuildArch: %{arch} + +Requires: python38 + +%description +STORAGE components, based on open source distributed storage customization. +%install +mkdir -p %{buildroot}/etc/dsms/dsms-deploy/ +cp dsms-deploy/*.conf %{buildroot}/etc/dsms/dsms-deploy/ +cp dsms-deploy/depend_list %{buildroot}/etc/dsms/dsms-deploy/ +cp dsms-deploy/dsms-deploy %{buildroot}/etc/dsms/dsms-deploy/ +cp dsms-deploy/*.tar.gz %{buildroot}/etc/dsms/dsms-deploy/ + +%post + + +%posttrans +mv /etc/dsms/dsms-deploy/dsms-deploy /usr/local/bin/dsms-deploy + + + +%preun + +%postun +rm -rf /usr/local/bin/dsms-deploy + + +%files +/etc/* + +%changelog \ No newline at end of file diff --git a/dsms_deploy/config/whl/ceph-deploy-2.0.1.tar.gz b/dsms_deploy/config/whl/ceph-deploy-2.0.1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..bc0ef86f7b029c24af5db83c112ba546d7db5196 GIT binary patch literal 121248 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%0A{eGw&LiUK9*gR-V* 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 g#35#}iaKF@Ve*gdg literal 0 HcmV?d00001 diff --git a/dsms_deploy/dsms-deploy.py b/dsms_deploy/dsms-deploy.py new file mode 100755 index 0000000..5377432 --- /dev/null +++ b/dsms_deploy/dsms-deploy.py @@ -0,0 +1,784 @@ +#!/usr/bin/python3 +import argparse +import io +import ipaddress +import json +import logging +import os +import sys +import time +from logging.config import dictConfig + +import paramiko + +try: + from typing import Dict, List, Tuple, Optional, Union, Any, NoReturn, Callable, IO +except ImportError: + pass + +VERSION = '1.0.0' +SSH_TIMEOUT = 10 +DEPLOY_USERNAME = 'root' +DEPLOY_PACKAGE = '/etc/dsms/dsms-deploy' +LOG_DIR = '/var/log/dsms/dsms-deploy' +CLUSTER_CONF = 'cluster.conf' +ADD_NODE_CONF = 'add-node.conf' +DEPEND_LIST = 'depend_list' +LEADER_NODE = 'NODE1' +SSH_PATH = '/root/.ssh' + +INIT_DIR = '/home/my-cluster' + +update_hosts = """ +#!/bin/bash +IP=$1 +HOSTNAME=$2 +if [ ! -n "$IP" ];then + echo "Please fill in parameter 1 as the IP address!" + exit 1 +fi +if [ ! -n "$HOSTNAME" ];then + echo "Please fill in parameter 2 as HOSTNAME!" + exit 1 +fi +ITEM="$IP $HOSTNAME" +HOSTS="/etc/hosts" +#update /etc/hosts file +add_hosts=true +while read line || [[ -n ${line} ]]; do + if [ "$ITEM" == "$line" ];then + add_hosts=false + break + else + i=1 + for host in $line;do + if [ $i -eq 2 ];then + if [ $host == $HOSTNAME ];then + #Delete the hosts entry that was the same as the current host but with a different ip + sed -i "/${line}/d" $HOSTS + fi + fi + i=`expr $i + 1` + done + continue + fi +done < $HOSTS + +if [ $add_hosts == true ];then + echo "$ITEM" >> $HOSTS +fi +""" + +# Log and console output config +logging_config = { + 'version': 1, + 'disable_existing_loggers': True, + 'formatters': { + 'paramiko': { + 'format': '%(asctime)s %(thread)x %(levelname)s %(message)s' + }, + 'dsms-storage': { + 'format': '%(asctime)s %(thread)x %(levelname)s DSMS-DEPLOY: %(message)s' + }, + 'console': { + 'format': '%(asctime)s %(message)s' + }, + }, + 'handlers': { + 'console': { + 'level': 'INFO', + 'class': 'logging.StreamHandler', + 'formatter': 'console', + + }, + 'log_file': { + 'level': 'DEBUG', + 'class': 'logging.handlers.RotatingFileHandler', + 'formatter': 'dsms-storage', + 'filename': '%s/dsms-deploy.log' % LOG_DIR, + 'maxBytes': 1024000, + 'backupCount': 1, + }, + 'paramiko_log_file': { + 'level': 'INFO', + 'class': 'logging.handlers.RotatingFileHandler', + 'formatter': 'paramiko', + 'filename': '%s/dsms-deploy.log' % LOG_DIR, + 'maxBytes': 1024000, + 'backupCount': 1, + } + }, + 'loggers': { + '': { + 'level': 'INFO', + 'handlers': ['console', 'log_file'], + }, + 'paramiko': { + 'level': 'INFO', + 'handlers': ['paramiko_log_file'], + 'propagate': False, + } + } +} + + +class termcolor: + yellow = '\033[93m' + red = '\033[31m' + end = '\033[0m' + + +class DsmsDeployException(Exception): + """ + Custom exception class + """ + + def __init__(self, message): + self.message = message + + def __str__(self): + return '{}{}{}'.format(termcolor.red, f"DsmsDeployException: {self.message}", termcolor.end) + + +class Node: + def __init__(self, ip, hostname, ssh_port, root_passwd, mon, repo_key_file, + repo_url, public_network, cluster_network, leader): + self.ip = ip + self.hostname = hostname + self.ssh_port = ssh_port + self.root_passwd = root_passwd + self.mon = mon + self.repo_key_file = repo_key_file + self.repo_url = repo_url + self.public_network = public_network + self.cluster_network = cluster_network + self.leader = leader + + +def dsms_require_root() -> None: + """Exit if the process is not running as root.""" + if os.geteuid() != 0: + sys.stderr.write('ERROR: dsms-deploy should be run as root\n') + sys.exit(1) + + +def find_nth(findstr, index, n): + start = findstr.find(index) + while start >= 0 and n > 1: + start = findstr.find(index, start + len(index)) + n -= 1 + return start + + +def valid_node(nodes, type): + for key, value in nodes.items(): + for field in ['ip', 'hostname', 'ssh_port', 'root_passwd']: + if not getattr(value, field, None): + raise DsmsDeployException(f'server {key} {field} is require field') + if type == 'new': + for field in ['public_network', 'cluster_network']: + if not getattr(value, field, None): + raise DsmsDeployException(f'init server {key} server {field} is require field') + try: + # Verify that the IP address format is correct + ipaddress.ip_address(value.ip) + except ValueError: + raise DsmsDeployException(f'server {key} IP address illegal') + + try: + # Verify that the ssh port format is correct + port = int(value.ssh_port) + if not 1 <= port <= 65535: + raise ValueError + except ValueError: + raise DsmsDeployException(f'server {key} SSH port {value.ssh_port} illegal') + + # Verify SSH connectivity + try: + with paramiko.SSHClient() as ssh: + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + ssh.connect(value.ip, port=value.ssh_port, username=DEPLOY_USERNAME, password=value.root_passwd) + try: + with ssh.open_sftp() as sftp: + sftp.listdir('.') + except Exception: + raise DsmsDeployException(f'server {key} SFTP config error, Please check the server config /etc/ssh/sshd_config') + except DsmsDeployException as e: + raise DsmsDeployException(e.message) + except paramiko.AuthenticationException as e: + raise DsmsDeployException(f'server {key} SSH Authentication fail, Please check the root passwd') + except Exception as e: + raise DsmsDeployException(f'server {key} SSH connect fail, Please check the ssh port') + + +def read_cluster_conf(conf_path): + nodes = {} + with open(conf_path) as f: + for line in f: + if line.strip() and not line.startswith("#") and line.startswith("NODE"): + key, value = line.strip().split('=') + if not value: + continue + node_name, attr_name = key.split('_', 1) + node = nodes.get(node_name) + if not node: + node = Node('', '', '', '', '', '', '', '', '', '') + nodes[node_name] = node + setattr(node, attr_name.lower(), value) + if node_name == LEADER_NODE: + setattr(node, 'leader', True) + if line.strip() and not line.startswith("#") and not line.startswith("NODE"): + key, value = line.strip().split('=') + if not value: + continue + for node in nodes.values(): + setattr(node, key.lower(), value) + valid_node(nodes, 'new') + return nodes + + +def read_add_conf(conf_path): + nodes = {} + with open(conf_path) as f: + for line in f: + if line.strip() and not line.startswith("#") and line.startswith("NEW_NODE"): + key, value = line.strip().split('=') + if not value: + continue + node_name = key[:find_nth(key, '_', 2)] + attr_name = key[find_nth(key, '_', 2) + 1:] + node = nodes.get(node_name) + if not node: + node = Node('', '', '', '', '', '', '', '', '', '') + nodes[node_name] = node + setattr(node, attr_name.lower(), value) + if line.strip() and not line.startswith("#") and line.startswith("REPO"): + key, value = line.strip().split('=') + if not value: + continue + for node in nodes.values(): + setattr(node, key.lower(), value) + valid_node(nodes, 'add') + return nodes + + +def run_ssh_command(server, username, password, command): + logger.info(f"{server} execute start: `{command}`") + ssh_client = paramiko.SSHClient() + ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + ssh_client.connect(hostname=server, username=username, password=password, + timeout=SSH_TIMEOUT, allow_agent=False, + look_for_keys=False) + + stdin, stdout, stderr = ssh_client.exec_command(command) + # Create a class file object + output_file = io.StringIO() + + # Real-time prints execution and writes to a class file object + for line in stdout: + logger.info(line.strip()) + output_file.write(line) + for line in stderr: + logger.info(line.strip()) + output_file.write(line) + + exit_code = stdout.channel.recv_exit_status() + # Save the execution to a variable + output = output_file.getvalue() + ssh_client.close() + + if exit_code == 0: + logger.info(f"{server} execute end: `{command}` success") + return output + else: + logger.error('{}{}{}'.format(termcolor.red, f"{server} execute end: `{command}` failed", termcolor.end)) + raise DsmsDeployException(output) + + +def run_ftp_command(local_file, server, username, password, remote_dir, + extract_command=None): + """ + Copy the local file to the remote server and execute extract command + + :param local_file: local file path + :param server: remote server address + :param username: remote server login username + :param password: remote server login password + :param remote_dir: remote destination directory + :param extract_command: extract command, optional parameter + :return: command execute result + """ + + # create ssh client + client = paramiko.SSHClient() + client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + client.connect(server, username=username, password=password, + allow_agent=False, look_for_keys=False) + + # create sftp client + sftp = client.open_sftp() + + # put local file to remote server + remote_file = os.path.join(remote_dir, os.path.basename(local_file)) + sftp.put(local_file, remote_file) + + # close sftp client + sftp.close() + + # execute extract command + if extract_command: + command = f'{extract_command} {remote_file} -C {remote_dir}' + stdin, stdout, stderr = client.exec_command(command) + # Create a class file object + output_file = io.StringIO() + + # Real-time prints execution and writes to a class file object + for line in stdout: + logger.info(line.strip()) + output_file.write(line) + for line in stderr: + logger.info(line.strip()) + output_file.write(line) + + exit_code = stdout.channel.recv_exit_status() + error = stderr.read().decode() + # Save the execution to a variable + output = output_file.getvalue() + client.close() + + if exit_code == 0: + logger.info(f"{server} execute: {command} success") + return output + else: + logger.info(error) + logger.error('{}{}{}'.format(termcolor.red, f"{server} execute: {command} failed", termcolor.end)) + raise DsmsDeployException(f"{server} execute: {command} failed") + + +def generate_remote_ssh_key(ssh_client): + """ + Generate an SSH key pair on the remote server + + :param ssh_client: remote server ssh client + :return: remote server public key + """ + + # check if the public key already exists on the remote server + _, stdout, _ = ssh_client.exec_command(f'ls {SSH_PATH}/id_rsa.pub') + public_key = stdout.read().decode().strip() + + if public_key: + # if the public key already exists, the current public key is read and returned + pass + else: + # if there is no public key, a new key pair is generated + _, stdout, stderr = ssh_client.exec_command( + f'ssh-keygen -t rsa -N "" -f {SSH_PATH}/id_rsa') + + # wait for the key to be generated + while not ssh_key_generated(ssh_client): + continue + + _, stdout, _ = ssh_client.exec_command(f'cat {SSH_PATH}/id_rsa.pub') + public_key = stdout.read().decode().strip() + return public_key + + +def ssh_key_generated(ssh_client): + """ + Check whether the SSH key is generated + + :param ssh_client:remote server ssh client + :return: True complete,False not yet + """ + _, stdout, _ = ssh_client.exec_command(f'ls {SSH_PATH}/id_rsa.pub') + public_key = stdout.read().decode().strip() + return bool(public_key) + + +def setup_ssh_trust(nodes): + for i, node in enumerate(nodes.values()): + try: + ssh_client = paramiko.SSHClient() + ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + ssh_client.connect(hostname=node.ip, username=DEPLOY_USERNAME, password=node.root_passwd, allow_agent=False, + look_for_keys=False) + + # Check that the id_rsa.pub file exists, if so, read the public key directly + public_key = generate_remote_ssh_key(ssh_client) + if public_key: + logger.info(f'remote server :{node.hostname} Public key get success') + else: + raise DsmsDeployException(f"remote server {node.hostname} generate remote ssh key failed") + + # copy the leader node's public key to the other node's authorization file + for j, other_node in enumerate(nodes.values()): + try: + other_ssh = paramiko.SSHClient() + other_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + other_ssh.connect(other_node.ip, username=DEPLOY_USERNAME, + password=other_node.root_passwd, + allow_agent=False, + look_for_keys=False) + sftp = other_ssh.open_sftp() + # Check if remote file exists + try: + sftp.stat(f'{SSH_PATH}/authorized_keys') + except FileNotFoundError: + other_ssh.exec_command(f'mkdir -p {SSH_PATH}') + other_ssh.exec_command(f'touch {SSH_PATH}/authorized_keys') + authorized_keys = sftp.file(f'{SSH_PATH}/authorized_keys', 'a+') + authorized_keys.seek(0) + keys = authorized_keys.read().decode().splitlines() + # verify whether it has been added first + if public_key not in keys: + authorized_keys.write(public_key + '\n') + logger.info(f'remote server :{other_node.hostname} add {node.hostname} public key success') + else: + logger.info(f'remote server :{other_node.hostname} exist {node.hostname} public key') + authorized_keys.close() + sftp.close() + other_ssh.close() + except Exception as e: + raise DsmsDeployException(f"remote server :{other_node.hostname} add {node.hostname} public key failed") + + ssh_client.connect(hostname=node.ip, username=DEPLOY_USERNAME, + password=node.root_passwd, + allow_agent=False, look_for_keys=False) + # prevent confirmation on first login + _, stdout, _ = ssh_client.exec_command( + f'ssh -o StrictHostKeyChecking=no root@{other_node.hostname}') + except Exception as e: + raise DsmsDeployException(f'Cluster node {node.hostname} grant credit failed {node.hostname}: {str(e)}') + return True + + +def configure_cluster(nodes): + """ + Configure the server cluster so that each node trusts each other and adds the corresponding + + :param nodes: cluster nodes + :return: execute result + """ + logger.info("Config cluster nodes start") + + client = paramiko.SSHClient() + client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + + try: + for i, node in enumerate(nodes.values()): + ip = node.ip + hostname = node.hostname + + client.connect(ip, username=DEPLOY_USERNAME, password=node.root_passwd, + timeout=SSH_TIMEOUT, + allow_agent=False, look_for_keys=False) + logger.info(f"set {ip} hostname to {hostname}") + command = f"hostnamectl set-hostname {hostname}" + client.exec_command(command) + + # Add all hostnames and IPs to /etc/hosts + for s in nodes.values(): + command = f"bash -s {s.ip} {s.hostname}" + stdin, stdout, stderr = client.exec_command(command) + stdin.write(update_hosts) + stdin.flush() + client.close() + # grant credit to other nodes + logger.info("cluster nodes grant credit start") + result = setup_ssh_trust(nodes) + logger.info('cluster nodes grant credit end') + except Exception as e: + raise DsmsDeployException(f'Configure_cluster failed: {str(e)}') + logger.info("Config cluster nodes end") + return result + + +def deploy_node(node): + if node.ip: + logger.info(f'start deploy server: {node.hostname}') + run_ssh_command(node.ip, DEPLOY_USERNAME, node.root_passwd, f'mkdir -p {DEPLOY_PACKAGE}') + depend_list = [] + whl_list = [] + ceph_rpm_list = [] + if node.repo_url: + logger.info('use customer repo') + gpgcheck = 0 + gpgkey = '' + if node.repo_url: + if node.repo_key_file: + gpgcheck = 1 + if node.repo_key_file.startswith('http'): + gpgkey = 'gpgkey=' + node.repo_key_file + else: + run_ftp_command( + local_file=node.repo_key_file, + server=node.ip, + username=DEPLOY_USERNAME, + password=node.root_passwd, + remote_dir=DEPLOY_PACKAGE, + ) + filename = os.path.basename(node.repo_key_file) + run_ssh_command(node.ip, DEPLOY_USERNAME, node.root_passwd, f'sudo rpm --import {DEPLOY_PACKAGE}/{filename}') + command = f'echo -e "[dsmsrepo]\nname=dsms-deploy\nbaseurl={node.repo_url}\ngpgcheck={gpgcheck}\nenabled=1\n{gpgkey}" | sudo tee /etc/yum.repos.d/dsms-deploy.repo > /dev/null' + run_ssh_command(node.ip, DEPLOY_USERNAME, node.root_passwd, command) + run_ssh_command(node.ip, DEPLOY_USERNAME, node.root_passwd, f"sudo yum clean all && sudo yum makecache") + + with open(DEPLOY_PACKAGE + "/" + DEPEND_LIST, 'r') as f: + for line in f: + if line.startswith('depend='): + depend_list.append(line.strip().split('=')[1]) + elif line.startswith('whl='): + whl_list.append(line.strip().split('=')[1]) + elif line.startswith('ceph_rpm='): + ceph_rpm_list.append(line.strip().split('=')[1]) + + # install all depend + depend_without_ext_list = [] + for depend in depend_list: + depend_without_ext = depend.rsplit('.', 1)[0] + depend_without_ext_list.append(depend_without_ext) + for ceph_rpm in ceph_rpm_list: + ceph_rpm_without_ext = ceph_rpm.rsplit('.', 1)[0] + depend_without_ext_list.append(ceph_rpm_without_ext) + depends = ' '.join(str(depend) for depend in depend_without_ext_list) + run_ssh_command(node.ip, DEPLOY_USERNAME, node.root_passwd, f"yum install -y {depends}") + if node.leader: + for whl in whl_list: + run_ssh_command(node.ip, DEPLOY_USERNAME, node.root_passwd, f"pip3 install {DEPLOY_PACKAGE}/{whl}") + + run_ssh_command(node.ip, DEPLOY_USERNAME, node.root_passwd, 'ceph -v') + + +def check_time_difference(nodes): + logger.info("Check servers time...") + + remote_times = {} + + for server in nodes.values(): + ssh_client = paramiko.SSHClient() + ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + + try: + ssh_client.connect(hostname=server.ip, username=DEPLOY_USERNAME, + password=server.root_passwd, timeout=SSH_TIMEOUT, + allow_agent=False, look_for_keys=False) + stdin, stdout, stderr = ssh_client.exec_command('date +%s') + remote_time = int(stdout.read().decode().strip()) + remote_times[server] = remote_time + except Exception as e: + raise DsmsDeployException(f"get {server.hostname} time failed: {str(e)}") + finally: + ssh_client.close() + + for server1 in remote_times: + for server2 in remote_times: + if server1 != server2: + time_difference = remote_times[server1] - remote_times[server2] + if time_difference > 1: + raise DsmsDeployException( + f"server time check failed. server1: {server1.hostname} server2: {server2.hostname}, time difference is: {time_difference}s") + logger.info("Check servers time pass") + + +def command_version(args): + return VERSION + + +def command_deploy(args): + logger.info('Starting deploy dsms-storage cluster...') + nodes = read_cluster_conf(DEPLOY_PACKAGE + '/' + CLUSTER_CONF) + + for node in nodes.values(): + deploy_node(node) + + logger.info('deploy dsms-storage cluster success') + + +def command_init(args): + logger.info("Initializing dsms-storage cluster...") + nodes = read_cluster_conf(DEPLOY_PACKAGE + '/' + CLUSTER_CONF) + check_time_difference(nodes) + configure_cluster(nodes) + leader = nodes.get(LEADER_NODE) + hostname = ' '.join([node.hostname for node in nodes.values()]) + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'mkdir -p {INIT_DIR}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, + f'cd {INIT_DIR};ceph-deploy new {hostname} --cluster-network={leader.cluster_network} --public-network={leader.public_network}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'cd {INIT_DIR};ceph-deploy --overwrite-conf config push {hostname}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'cd {INIT_DIR};ceph-deploy mon create-initial') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'cd {INIT_DIR};ceph-deploy admin {hostname}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'cd {INIT_DIR};ceph-deploy mgr create {hostname}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'cd {INIT_DIR};ceph-deploy mds create {hostname}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph mgr module enable cephadm --force') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph mgr module enable prometheus --force') + time.sleep(20) # give some room to start + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph orch set backend cephadm') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph cephadm generate-key') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph cephadm get-pub-key > ~/ceph.pub') + + for node in nodes.values(): + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'ssh-copy-id -f -i ~/ceph.pub root@{node.hostname}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, + f'scp /home/my-cluster/ceph.bootstrap-osd.keyring root@{node.hostname}:/var/lib/ceph/bootstrap-osd/ceph.keyring') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'ceph orch host add {node.hostname}') + + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph orch apply prometheus') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph orch apply node-exporter') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph restful create-self-signed-cert') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph restful create-key admin') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph config set mon mon_allow_pool_delete true') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph config set global rbd_default_features 1') + time.sleep(5) # give some room to start + command_info('') + logger.info('init dsms-storage cluster success') + + +def command_info(args): + logger.info("Getting dsms-storage cluster information") + + nodes = read_cluster_conf(DEPLOY_PACKAGE + '/' + CLUSTER_CONF) + leader = nodes.get(LEADER_NODE) + mgr_services = run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph mgr services') + auth_key = run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, 'ceph restful list-keys') + parsed_data = json.loads(mgr_services) + mgr_service = parsed_data["restful"] + parsed_data = json.loads(auth_key) + admin_value = parsed_data["admin"] + + logger.info( + f"Get dsms-storage cluster information finish \n\tCluster server address: {mgr_service}\n\tCluster server admin key: {admin_value}") + + +def command_add_node(args): + logger.info("Adding node to dsms-storage...") + cluster_nodes = read_cluster_conf(DEPLOY_PACKAGE + '/' + CLUSTER_CONF) + add_nodes = read_add_conf(DEPLOY_PACKAGE + '/' + ADD_NODE_CONF) + + for node in add_nodes.values(): + deploy_node(node) + all_nodes = cluster_nodes.copy() + all_nodes.update(add_nodes) + check_time_difference(all_nodes) + configure_cluster(all_nodes) + leader = cluster_nodes.get(LEADER_NODE) + for add_node in add_nodes.values(): + logger.info(f"adding {add_node.hostname} to dsms-storage") + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, + f'cd {INIT_DIR};ceph-deploy --overwrite-conf config push {add_node.hostname}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'cd {INIT_DIR};ceph-deploy admin {add_node.hostname}') + if add_node.mon: + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'cd {INIT_DIR};ceph-deploy mon create {add_node.hostname}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'cd {INIT_DIR};ceph-deploy mgr create {add_node.hostname}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'cd {INIT_DIR};ceph-deploy mds create {add_node.hostname}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'ssh-copy-id -f -i ~/ceph.pub root@{add_node.hostname}') + + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, + f'scp /home/my-cluster/ceph.bootstrap-osd.keyring root@{add_node.hostname}:/var/lib/ceph/bootstrap-osd/ceph.keyring') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'ceph orch host add {add_node.hostname}') + logger.info(f"add {add_node.hostname} to dsms-storage complete") + logger.info("Added node to dsms-storage success") + + +def command_remove_node(args): + logger.info("Removing node from dsms-storage...") + cluster_nodes = read_cluster_conf(DEPLOY_PACKAGE + '/' + CLUSTER_CONF) + leader = cluster_nodes.get(LEADER_NODE) + for node in args.host: + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'ceph-deploy mon destroy {node}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'ceph-deploy purge {node}') + run_ssh_command(leader.ip, DEPLOY_USERNAME, leader.root_passwd, f'ceph-deploy purgedata {node}') + logger.info("Removed node from dsms-storage success") + + +def command_rm_cluster(args): + # Removing the dsms-storage cluster and uninstall package + logger.info('Removing the dsms-storage cluster...') + nodes = read_cluster_conf(DEPLOY_PACKAGE + '/' + CLUSTER_CONF) + + for node in nodes.values(): + logger.info(f'Starting remove node: {node.hostname}') + run_ssh_command(node.ip, DEPLOY_USERNAME, node.root_passwd, f'ceph-deploy purge {node.hostname}') + run_ssh_command(node.ip, DEPLOY_USERNAME, node.root_passwd, f'ceph-deploy purgedata {node.hostname}') + run_ssh_command(node.ip, DEPLOY_USERNAME, node.root_passwd, f'rm -rf {INIT_DIR}/*') + run_ssh_command(node.ip, DEPLOY_USERNAME, node.root_passwd, f'rm -rf {DEPLOY_PACKAGE}/*') + logger.info('Removed the dsms-storage cluster success') + + +def _get_parser(): + # type: () -> argparse.ArgumentParser + parser = argparse.ArgumentParser( + description='Bootstrap dsms storage.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + subparsers = parser.add_subparsers(help='sub-command') + + parser_version = subparsers.add_parser('version', help='Show dsms-deploy version') + parser_version.set_defaults(func=command_version) + + parser_deploy = subparsers.add_parser('deploy', help='Deploy dsms-storage package') + parser_deploy.set_defaults(func=command_deploy) + + parser_init = subparsers.add_parser('init', help='Init dsms-storage cluster') + parser_init.set_defaults(func=command_init) + + parser_add_node = subparsers.add_parser('addNode', help='Add a node to an existing cluster') + parser_add_node.set_defaults(func=command_add_node) + + parser_remove_node = subparsers.add_parser('removeNode', help='Remove a node for an existing cluster') + parser_remove_node.set_defaults(func=command_remove_node) + parser_remove_node.add_argument( + 'host', + metavar='HOST', + nargs='+', + help='hosts to purge Ceph data from', + ) + + parser_rm_cluster = subparsers.add_parser('rmCluster', help='Remove all daemons for this cluster') + parser_rm_cluster.set_defaults(func=command_rm_cluster) + + parser_info = subparsers.add_parser('info', help='Get cluster info') + parser_info.set_defaults(func=command_info) + + return parser + + +def _parse_args(av): + parser = _get_parser() + args = parser.parse_args(av) + + return args + + +if __name__ == '__main__': + + # get args + try: + av = injected_argv # type: ignore + except NameError: + av = sys.argv[1:] + + if not av: + sys.stderr.write('No command specified; pass -h or --help for usage\n') + sys.exit(1) + # dsms_require_root() + + # init log + if not os.path.exists(LOG_DIR): + os.makedirs(LOG_DIR) + dictConfig(logging_config) + + logger = logging.getLogger() + + logger.info("dsms-deploy params %s" % av) + # parse args + args = _parse_args(av) + + try: + r = args.func(args) + except DsmsDeployException as e: + sys.stderr.write('ERROR: %s\n' % e) + sys.exit(1) + if not r: + r = 0 + sys.exit(r) -- Gitee