diff --git a/namekoplus/chassis-agent/rabbitmq/docker-compose-rabbitmq.yml b/namekoplus/chassis-agent/rabbitmq/docker-compose-rabbitmq.yml new file mode 100644 index 0000000..0b5b0fb --- /dev/null +++ b/namekoplus/chassis-agent/rabbitmq/docker-compose-rabbitmq.yml @@ -0,0 +1,25 @@ +version: "3" + +services: + rabbitmq: + image: rabbitmq:3-management + container_name: 'rabbitmq' + hostname: 'rabbitmq' + ports: + - "5672:5672" + - "15672:15672" + - "25672:25672" + volumes: + - rabbitmq_data:/var/lib/rabbitmq + - rabbitmq_log:/var/log/rabbitmq + environment: + RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-admin} + RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-admin} + restart: always + + +volumes: + rabbitmq_data: + driver: local + rabbitmq_log: + driver: local \ No newline at end of file diff --git a/namekoplus/command.py b/namekoplus/command.py index 597223f..8d6844c 100644 --- a/namekoplus/command.py +++ b/namekoplus/command.py @@ -3,6 +3,22 @@ import shutil from contextlib import contextmanager import click +from python_on_whales import DockerException, ClientNotFoundError, DockerClient, docker as docker_testing + + +def check_docker(): + try: + docker_testing.ps() + except ClientNotFoundError: + click.echo('Please install docker first', err=True) + raise + except DockerException: + click.echo('Please start docker correctly', err=True) + raise + + if not docker_testing.compose.is_installed(): + click.echo('Please install docker-compose first', err=True) + raise @contextmanager @@ -21,9 +37,8 @@ def status(status_msg: str, newline: bool = False, quiet: bool = False): def get_template_directory() -> str: - """Return the directory where nameko_plus setup templates are found. - - This method is used by the nameko_plus ``init`` commands. + """ + Return the directory where nameko_plus setup templates are found. """ import namekoplus @@ -31,6 +46,16 @@ def get_template_directory() -> str: return os.path.join(package_dir, 'templates') +def get_agent_directory() -> str: + """ + Return the directory where nameko_plus setup agent are found. + """ + import namekoplus + + package_dir = os.path.abspath(os.path.dirname(namekoplus.__file__)) + return os.path.join(package_dir, 'chassis-agent') + + @click.group() def cli(): pass @@ -74,11 +99,51 @@ def init(directory, _type): @cli.command() -def start(): +@click.option('-m', '--middleware', + required=True, + type=click.Choice(['rabbitmq'], case_sensitive=False), + help='The middleware name') +@click.option('-u', '--user', + required=False, + help='The user name of the middleware') +@click.option('-p', '--password', + required=False, + help='The password of the middleware') +def start(middleware, user, password): """ - Start a middleware, such as RabbitMQ. + Start a middleware that the nameko service depends on. """ - click.echo('Initialized the database') + check_docker() + + if user and password: + os.environ['RABBITMQ_DEFAULT_USER'] = user + os.environ['RABBITMQ_DEFAULT_PASS'] = password + + docker_compose_file_dir = os.path.join(get_agent_directory(), middleware) + for file_ in os.listdir(docker_compose_file_dir): + compose_file_path = os.path.join(docker_compose_file_dir, file_) + with status(f'Starting {middleware}'): + docker = DockerClient(compose_files=[compose_file_path]) + docker.compose.up(detach=True) + + +@cli.command() +@click.option('-m', '--middleware', + required=True, + type=click.Choice(['rabbitmq'], case_sensitive=False), + help='The middleware name') +def stop(middleware): + """ + Stop a middleware that the nameko service depends on. + """ + check_docker() + + docker_compose_file_dir = os.path.join(get_agent_directory(), middleware) + for file_ in os.listdir(docker_compose_file_dir): + compose_file_path = os.path.join(docker_compose_file_dir, file_) + with status(f'Stoping {middleware}'): + docker = DockerClient(compose_files=[compose_file_path]) + docker.compose.down() if __name__ == '__main__': diff --git a/setup.py b/setup.py index 9edefe5..3fc3c41 100644 --- a/setup.py +++ b/setup.py @@ -9,12 +9,16 @@ with open(path.join(here, 'README.md'), encoding='utf-8') as f: setup( name='namekoplus', - version='0.1.2', + version='0.2.0', description='A lightweight Python distributed microservice solution', long_description=long_description, long_description_content_type='text/markdown', - url='https://github.com/Bryanthelol/namekoplus', - + url='', + project_urls={ + 'Documentation': 'https://doc.bearcatlog.com/', + 'Source Code': 'https://github.com/Bryanthelol/namekoplus', + 'Bug Tracker': 'https://github.com/Bryanthelol/namekoplus/issues', + }, author='Bryant He', author_email='bryantsisu@qq.com', @@ -45,20 +49,19 @@ setup( install_requires=[ 'nameko==3.0.0rc11', - 'nameko-sentry==1.0.0', - 'nameko-tracer==1.4.0', 'click==8.1.5', - 'pytest==7.4.0', - 'environs==9.5.0', - 'logstash_formatter==0.5.17', - 'statsd==4.0.1', - 'tenacity==8.2.2', - 'cachetools==5.3.0', - 'circuitbreaker==2.0.0', - 'shortuuid==1.0.11', - 'cryptography' + 'python-on-whales==0.62.0', + 'pytest==7.4.0' ], extras_require={ + 'ha': ['tenacity==8.2.2', + 'cachetools==5.3.0', + 'circuitbreaker==2.0.0', + 'statsd==4.0.1', + 'logstash_formatter==0.5.17', + 'nameko-sentry==1.0.0', + 'nameko-tracer==1.4.0', + 'shortuuid==1.0.11'], 'apiflask': ['apiflask>=1.3.1', 'gevent>=22.10.2', 'gunicorn==20.1.0'], @@ -68,6 +71,8 @@ setup( 'sqlalchemy==2.0.15', 'sqlacodegen==2.3.0', 'alembic==1.11.1'], - 'dev': ['mako==1.2.4'], + 'ssl': ['cryptography'], + 'dev': ['mako==1.2.4', + 'environs==9.5.0'] }, )