diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 270d2c2..41f84c9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,10 +13,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.12.6 uses: actions/setup-python@v5 with: - python-version: 3.12.2 + python-version: 3.12.6 - name: Install dependencies run: | python -m pip install --upgrade pip @@ -31,10 +31,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up Python 3.12.2 + - name: Set up Python 3.12.6 uses: actions/setup-python@v5 with: - python-version: 3.12.2 + python-version: 3.12.6 - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/Makefile b/Makefile index f33a723..841f647 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,20 @@ -.PHONY: push-all +.PHONY: push-all, build, publish -VERSION=0.2.2 +VERSION=1.0.0 IMAGE_NAME=gleif/vlei +LATEST_TAG=$(IMAGE_NAME):latest +VERSION_TAG=$(IMAGE_NAME):$(VERSION) push-all: @docker push $(IMAGE_NAME) --all-tags -.PHONY: build-vlei build: - @docker buildx build --load \ + @docker build \ --platform=linux/amd64,linux/arm64 \ + --no-cache \ -f container/Dockerfile \ - --tag $(IMAGE_NAME):latest \ - --tag $(IMAGE_NAME):$(VERSION) \ + --tag $(LATEST_TAG) \ + --tag $(VERSION_TAG) \ . publish: diff --git a/setup.py b/setup.py index cfeedbf..c79ad95 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ setup( name='vlei', - version='0.2.2', # also change in src/vlei/__init__.py + version='1.0.0', # also change in src/vlei/__init__.py license='Apache Software License 2.0', description='Verifiable Legal Entity Identifier', long_description=long_description, @@ -72,22 +72,21 @@ keywords=[ 'keri','acdc','vlei' ], - python_requires='>=3.12.2', + python_requires='>=3.12.6', install_requires=[ 'hio==0.6.14', - 'keri>=1.2.2', + 'keri>=1.2.6', 'falcon>=4.0.2', 'multicommand>=1.0.0' ], extras_require={ }, tests_require=[ - 'coverage>=7.6.10', - 'pytest>=8.3.4', + 'coverage>=7.8.0', + 'pytest>=8.3.5', 'requests==2.32.3' ], setup_requires=[ - 'setuptools==75.8.2' ], entry_points={ 'console_scripts': [ diff --git a/src/vlei/__init__.py b/src/vlei/__init__.py index f8ff8c6..cc18f6e 100644 --- a/src/vlei/__init__.py +++ b/src/vlei/__init__.py @@ -1,4 +1,4 @@ # -*- encoding: utf-8 -*- -__version__ = '0.2.2' # also change in setup.py +__version__ = '1.0.0' # also change in setup.py diff --git a/src/vlei/app/shutdown.py b/src/vlei/app/shutdown.py index 2fcfd9d..4876432 100644 --- a/src/vlei/app/shutdown.py +++ b/src/vlei/app/shutdown.py @@ -8,24 +8,28 @@ class GracefulShutdownDoer(doing.Doer): """ Shuts all Agency agents down before exiting the Doist loop, performing a graceful shutdown. - Sets up signal handler in the Doer.enter lifecycle method and exits the Doist scheduler loop in Doer.exit + Sets up signal handler in the Doer.enter lifecycle method and exits the Doist scheduler by raising + the KeyboardInterrupt that will be caught by the parent Doist. Checks for the shutdown flag in the Doer.recur lifecycle method. """ - def __init__(self, doist, **kwa): + def __init__(self, **kwa): """ Parameters: - doist (Doist): The Doist running this Doer kwa (dict): Additional keyword arguments for Doer initialization """ - self.doist: Doist = doist self.shutdown_received = False super().__init__(**kwa) def handle_sigterm(self, signum, frame): """Handler function for SIGTERM""" - logger.info(f"Received SIGTERM, initiating graceful shutdown.") - self.shutdown_received = True + logger.info(f"Received SIGTERM, throwing interrupt to initiate graceful shutdown.") + raise KeyboardInterrupt() + + def handle_sigint(self, signum, frame): + """Handler function for SIGINT""" + logger.info(f"Received SIGINT, throwing interrupt to initiate graceful shutdown.") + raise KeyboardInterrupt() def enter(self): """ @@ -34,6 +38,7 @@ def enter(self): """ # Register signal handler signal.signal(signal.SIGTERM, self.handle_sigterm) + signal.signal(signal.SIGINT, self.handle_sigint) logger.info("Registered signal handlers for SIGTERM and SIGINT") def recur(self, tock=0.0): @@ -51,5 +56,4 @@ def exit(self): Exits the Doist loop. Lifecycle method called once when the Doist running this Doer exits the context for this Doer. """ - logger.info(f"Shutting down main Doist loop") - self.doist.exit() \ No newline at end of file + logger.info(f"Graceful shutdown finished") \ No newline at end of file diff --git a/src/vlei/server.py b/src/vlei/server.py index 45847d6..5c93807 100644 --- a/src/vlei/server.py +++ b/src/vlei/server.py @@ -14,6 +14,7 @@ from hio.core import http, tcp from keri import help +import vlei from vlei.app import serving from vlei.app.shutdown import GracefulShutdownDoer @@ -40,6 +41,8 @@ help="TLS server signed certificate (public key) file") parser.add_argument("--cafilepath", action="store", required=False, default=None, help="TLS server CA certificate chain") +parser.add_argument("--loglevel", action="store", required=False, default="INFO", + help="Set log level to DEBUG | INFO | WARNING | ERROR | CRITICAL. Default is INFO") logger = help.ogler.getLogger() @@ -55,6 +58,7 @@ class VLEIConfig: credDir: str = "./samples/acdc/" # Well known OOBI directory oobiDir: str = "./samples/oobis/" + logLevel: str = "CRITICAL" # TLS key material keypath: str = None certpath: str = None @@ -93,9 +97,9 @@ def setupVLEIDoers(config: VLEIConfig): certpath = config.certpath cafilepath = config.cafilepath if keypath is not None and certpath is not None and cafilepath is not None: - logger.info(f"vLEI-server starting on port {port} with TLS enabled") + logger.info(f"vLEI-server v{vlei.__version__} starting on port {port} with TLS enabled") else: - logger.info(f"vLEI-server starting on port {port} with TLS disabled") + logger.info(f"vLEI-server v{vlei.__version__} starting on port {port} with TLS disabled") server = createHttpServer(port=int(config.http), app=app, keypath=config.keypath, certpath=config.certpath, cafilepath=config.cafilepath) @@ -112,14 +116,20 @@ def vLEIDoist(doers: List[Doer]): """Creates a Doist that will run the vLEI server.""" tock = 0.03125 doist = doing.Doist(limit=0.0, tock=tock, real=True) - doers.append(GracefulShutdownDoer(doist=doist)) + doers.append(GracefulShutdownDoer()) doist.doers = doers return doist def launch(config: VLEIConfig): """Launches the vLEI server by calling Doist.do() on the Doers that make up the server.""" - logger.setLevel(logging.INFO) + # log level + base_formatter = logging.Formatter('%(asctime)s [vLEI-server] %(module)s.%(funcName)s-%(lineno)s %(levelname)-8s %(message)s') + base_formatter.default_msec_format = None + help.ogler.baseConsoleHandler.setFormatter(base_formatter) + help.ogler.level = logging.getLevelName(config.logLevel) + logger.setLevel(help.ogler.level) + doist = vLEIDoist(setupVLEIDoers(config)) doist.do() # Enters the doist loop until shutdown logger.info("vLEI-server stopped") @@ -132,6 +142,7 @@ def main(): schemaDir=args.schemaDir, credDir=args.credDir, oobiDir=args.oobiDir, + logLevel=args.loglevel.upper(), keypath=args.keypath, certpath=args.certpath, cafilepath=args.cafilepath