forked from ISPsystem/isp-maintenance
		
	Add: devtools, Makefile
This commit is contained in:
		
							parent
							
								
									0f96d0f956
								
							
						
					
					
						commit
						287216d975
					
				
							
								
								
									
										13
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | build: | ||||||
|  | 	python3 ./scripts/devtools/dev.py builder docker-compose build | ||||||
|  | destroy: | ||||||
|  | 	python3 ./scripts/devtools/dev.py builder docker-compose destroy | ||||||
|  | up: | ||||||
|  | 	python3 ./scripts/devtools/dev.py runner docker-compose up | ||||||
|  | down: | ||||||
|  | 	python3 ./scripts/devtools/dev.py runner docker-compose down | ||||||
|  | restart: | ||||||
|  | 	python3 ./scripts/devtools/dev.py runner docker-compose restart | ||||||
|  | setup: build up | ||||||
|  | 
 | ||||||
|  | .PHONY: exec setup build | ||||||
							
								
								
									
										59
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | |||||||
|  | # ? docker-compose.yml for development environment | ||||||
|  | 
 | ||||||
|  | # ! To start development you need to create a directory ./dummy_platform. | ||||||
|  | # ? Place files from the test platform into it: | ||||||
|  | # ? VM6: | ||||||
|  | # ?     /opt/ispsystem/vm/config.json - configuration file | ||||||
|  | # ?     /opt/ispsystem/vm/mysql - database directory | ||||||
|  | # ? DCI6: | ||||||
|  | # ?     /opt/ispsystem/dci/config.json - configuration file | ||||||
|  | # ?     /opt/ispsystem/dci/mysql - database directory | ||||||
|  | 
 | ||||||
|  | # ? Create ./.env file and fill it with required vars: | ||||||
|  | # ? PLATFORM_TYPE='vm' | ||||||
|  | # ? Database container: | ||||||
|  | # ? MYSQL_DATABASE="database name" | ||||||
|  | # ? MYSQL_ROOT_PASSWORD="super secret password from config.json" | ||||||
|  | 
 | ||||||
|  | # ? Launch:  | ||||||
|  | # ?     docker-compose up -d --force-recreate | ||||||
|  | # ?     docker attach mgrctl | ||||||
|  | 
 | ||||||
|  | services: | ||||||
|  |   mgrctl: | ||||||
|  |     container_name: mgrctl | ||||||
|  |     restart: unless-stopped | ||||||
|  |     build: | ||||||
|  |       context: . | ||||||
|  |       args: | ||||||
|  |         - APP_VERSION=${APP_VERSION} | ||||||
|  |         - APP_DIR=${APP_DIR} | ||||||
|  |         - SRC_DIR=${SRC_DIR} | ||||||
|  |         - PKG_NAME=${PKG_NAME} | ||||||
|  |         - PKG_VERSION=${PKG_VERSION} | ||||||
|  |     networks: | ||||||
|  |       vm_box_net: null | ||||||
|  |     volumes: | ||||||
|  |       - type: bind | ||||||
|  |         source: ./dummy_platform/opt/ispsystem/${PLATFORM_TYPE}/config.json | ||||||
|  |         target: /opt/ispsystem/${PLATFORM_TYPE}/config.json | ||||||
|  |     env_file: | ||||||
|  |       - ./.env | ||||||
|  |     tty: true | ||||||
|  |     stdin_open: true | ||||||
|  |   mysql: | ||||||
|  |     container_name: mysql | ||||||
|  |     image: docker-registry.ispsystem.com/mysql:5 | ||||||
|  |     volumes: | ||||||
|  |       - ./dummy_platform/opt/ispsystem/${PLATFORM_TYPE}/mysql:/var/lib/mysql | ||||||
|  |     env_file: | ||||||
|  |       - ./.env | ||||||
|  |     labels: | ||||||
|  |       autoconf_mysql: "true" | ||||||
|  |     networks: | ||||||
|  |       vm_box_net: null | ||||||
|  |     command: --group-concat-max-len=131072 --max-connections=1000 --optimizer-search-depth=0 | ||||||
|  | 
 | ||||||
|  | networks: | ||||||
|  |   vm_box_net: | ||||||
|  |     driver: bridge | ||||||
							
								
								
									
										10
									
								
								scripts/devtools/cli/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								scripts/devtools/cli/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | # █▀▄▀█ █▀▀ ▀█▀ ▄▀█ ▀ | ||||||
|  | # █░▀░█ ██▄ ░█░ █▀█ ▄ | ||||||
|  | # -- -- -- -- -- -- - | ||||||
|  | __author__ = "MOIS3Y" | ||||||
|  | __credits__ = ["Stepan Zhukovsky"] | ||||||
|  | __license__ = "MIT" | ||||||
|  | __version__ = "0.1.0" | ||||||
|  | __maintainer__ = "Stepan Zhukovsky" | ||||||
|  | __email__ = "stepan@zhukovsky.me" | ||||||
|  | __status__ = "Development" | ||||||
							
								
								
									
										50
									
								
								scripts/devtools/cli/builder.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								scripts/devtools/cli/builder.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | #!/usr/bin/env python3 | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | import click | ||||||
|  | import sh | ||||||
|  | 
 | ||||||
|  | from .lazy_group import LazyGroup | ||||||
|  | from .utils import abort_if_false | ||||||
|  | from . import settings | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @click.group() | ||||||
|  | def cli1(): | ||||||
|  |     pass | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @click.group( | ||||||
|  |     cls=LazyGroup, | ||||||
|  |     lazy_subcommands={'docker-compose': 'cli.builder.docker_compose'}, | ||||||
|  | ) | ||||||
|  | def cli2(): | ||||||
|  |     pass | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @click.group(help='cmd for build/destroy project in docker containers') | ||||||
|  | def docker_compose(): | ||||||
|  |     pass | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @docker_compose.command(help='cmd for build project in docker containers') | ||||||
|  | def build(): | ||||||
|  |     with sh.contrib.sudo(password=settings.SUDO_PASSWORD, _with=True): | ||||||
|  |         sh.docker_compose('-f', settings.COMPOSE_FILE, 'build', _fg=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @docker_compose.command(help='cmd for destroy project in docker containers') | ||||||
|  | @click.option( | ||||||
|  |     '--yes', | ||||||
|  |     is_flag=True, | ||||||
|  |     callback=abort_if_false, | ||||||
|  |     expose_value=False, | ||||||
|  |     prompt='Are you sure you want to destroy docker containers') | ||||||
|  | def destroy(): | ||||||
|  |     with sh.contrib.sudo(password=settings.SUDO_PASSWORD, _with=True): | ||||||
|  |         sh.docker_compose('-f', settings.COMPOSE_FILE, 'down',  _fg=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | cli = click.CommandCollection( | ||||||
|  |     sources=[cli1, cli2], | ||||||
|  |     help='cmd for building the project' | ||||||
|  | ) | ||||||
							
								
								
									
										39
									
								
								scripts/devtools/cli/lazy_group.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								scripts/devtools/cli/lazy_group.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | import importlib | ||||||
|  | import click | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class LazyGroup(click.Group): | ||||||
|  |     def __init__(self, *args, lazy_subcommands=None, **kwargs): | ||||||
|  |         super().__init__(*args, **kwargs) | ||||||
|  |         # lazy_subcommands is a map of the form: | ||||||
|  |         # | ||||||
|  |         #   {command-name} -> {module-name}.{command-object-name} | ||||||
|  |         # | ||||||
|  |         self.lazy_subcommands = lazy_subcommands or {} | ||||||
|  | 
 | ||||||
|  |     def list_commands(self, ctx): | ||||||
|  |         base = super().list_commands(ctx) | ||||||
|  |         lazy = sorted(self.lazy_subcommands.keys()) | ||||||
|  |         return base + lazy | ||||||
|  | 
 | ||||||
|  |     def get_command(self, ctx, cmd_name): | ||||||
|  |         if cmd_name in self.lazy_subcommands: | ||||||
|  |             return self._lazy_load(cmd_name) | ||||||
|  |         return super().get_command(ctx, cmd_name) | ||||||
|  | 
 | ||||||
|  |     def _lazy_load(self, cmd_name): | ||||||
|  |         # lazily loading a command, | ||||||
|  |         # first get the module name and attribute name | ||||||
|  |         import_path = self.lazy_subcommands[cmd_name] | ||||||
|  |         modname, cmd_object_name = import_path.rsplit(".", 1) | ||||||
|  |         # do the import | ||||||
|  |         mod = importlib.import_module(modname) | ||||||
|  |         # get the Command object from that module | ||||||
|  |         cmd_object = getattr(mod, cmd_object_name) | ||||||
|  |         # check the result to make debugging easier | ||||||
|  |         if not isinstance(cmd_object, click.BaseCommand): | ||||||
|  |             raise ValueError( | ||||||
|  |                 f"Lazy loading of {import_path} failed by returning " | ||||||
|  |                 "a non-command object" | ||||||
|  |             ) | ||||||
|  |         return cmd_object | ||||||
							
								
								
									
										57
									
								
								scripts/devtools/cli/runner.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								scripts/devtools/cli/runner.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | #!/usr/bin/env python3 | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | import click | ||||||
|  | import sh | ||||||
|  | 
 | ||||||
|  | from .lazy_group import LazyGroup | ||||||
|  | from . import settings | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @click.group() | ||||||
|  | def cli1(): | ||||||
|  |     pass | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @click.group( | ||||||
|  |     cls=LazyGroup, | ||||||
|  |     lazy_subcommands={'docker-compose': 'cli.runner.docker_compose'}, | ||||||
|  | ) | ||||||
|  | def cli2(): | ||||||
|  |     pass | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @click.group(help='cmd for run/stop/restart project in docker containers') | ||||||
|  | def docker_compose(): | ||||||
|  |     pass | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @docker_compose.command(help='cmd for run project docker containers') | ||||||
|  | def up(): | ||||||
|  |     with sh.contrib.sudo(password=settings.SUDO_PASSWORD, _with=True): | ||||||
|  |         sh.docker_compose('-f', settings.COMPOSE_FILE, 'up', '-d', _fg=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @docker_compose.command(help='cmd for down project docker containers') | ||||||
|  | def down(): | ||||||
|  |     with sh.contrib.sudo(password=settings.SUDO_PASSWORD, _with=True): | ||||||
|  |         sh.docker_compose('-f', settings.COMPOSE_FILE, 'down', _fg=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @docker_compose.command(help='cmd for restart project docker containers') | ||||||
|  | def restart(): | ||||||
|  |     with sh.contrib.sudo(password=settings.SUDO_PASSWORD, _with=True): | ||||||
|  |         sh.docker_compose( | ||||||
|  |             '-f', | ||||||
|  |             settings.COMPOSE_FILE, | ||||||
|  |             'up', | ||||||
|  |             '-d', | ||||||
|  |             '--build', | ||||||
|  |             '--force-recreate', | ||||||
|  |             _fg=True | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | cli = click.CommandCollection( | ||||||
|  |     sources=[cli1, cli2], | ||||||
|  |     help='cmd for running the project standalone or docker-compose' | ||||||
|  | ) | ||||||
							
								
								
									
										18
									
								
								scripts/devtools/cli/settings.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								scripts/devtools/cli/settings.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | import pathlib | ||||||
|  | from environs import Env | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Path: | ||||||
|  | ROOT_DIR = pathlib.Path(__file__).resolve().parent.parent.parent.parent | ||||||
|  | PROJECT_DIR = ROOT_DIR / 'mgrctl' | ||||||
|  | COMPOSE_FILE = ROOT_DIR / 'docker-compose.yml' | ||||||
|  | 
 | ||||||
|  | # Init environment: | ||||||
|  | env = Env() | ||||||
|  | 
 | ||||||
|  | # read .env file, if it exists | ||||||
|  | # reed more about .env file here: https://github.com/sloria/environs | ||||||
|  | env.read_env(path=ROOT_DIR / '.env') | ||||||
|  | 
 | ||||||
|  | # ! insecure save sudo password wherever | ||||||
|  | SUDO_PASSWORD = env.str('SUDO_PASSWORD', None) | ||||||
							
								
								
									
										15
									
								
								scripts/devtools/cli/utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								scripts/devtools/cli/utils.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | import click | ||||||
|  | 
 | ||||||
|  | from . import __version__ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def print_version(ctx, param, value): | ||||||
|  |     if not value or ctx.resilient_parsing: | ||||||
|  |         return | ||||||
|  |     click.echo(__version__) | ||||||
|  |     ctx.exit() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def abort_if_false(ctx, param, value): | ||||||
|  |     if not value: | ||||||
|  |         ctx.abort() | ||||||
							
								
								
									
										30
									
								
								scripts/devtools/dev.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										30
									
								
								scripts/devtools/dev.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | #!/usr/bin/env python3 | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | import click | ||||||
|  | 
 | ||||||
|  | from cli.lazy_group import LazyGroup | ||||||
|  | from cli.utils import print_version | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @click.group( | ||||||
|  |     cls=LazyGroup, | ||||||
|  |     lazy_subcommands={ | ||||||
|  |         'builder': 'cli.builder.cli', | ||||||
|  |         'runner': 'cli.runner.cli', | ||||||
|  |     }, | ||||||
|  |     help='dev.py CLI tool for dev actions', | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     '--version', | ||||||
|  |     is_flag=True, | ||||||
|  |     callback=print_version, | ||||||
|  |     expose_value=False, | ||||||
|  |     is_eager=True, | ||||||
|  |     help='Print version and exit' | ||||||
|  | ) | ||||||
|  | def cli(): | ||||||
|  |     pass | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     cli() | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user