-
-
Notifications
You must be signed in to change notification settings - Fork 1
feat(foreground): Add foreground command #281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
5a82809
add validation for non remote dependencies
hubertdeng123 6ecedd5
fix some tests
hubertdeng123 eccadb2
add supervisor config validation
hubertdeng123 b1e2dc7
add two more tests
hubertdeng123 d9c5fc8
change structure of dependeny to also pass in type
hubertdeng123 7e4beff
fix more stuff
hubertdeng123 eb39a55
remove print statement
hubertdeng123 6d22675
fix tests
hubertdeng123 03b77d4
actually fix tests
hubertdeng123 c92b0c1
fix dependency_type
hubertdeng123 0a8c34f
add supervisor program to up
hubertdeng123 f64c964
merge main
hubertdeng123 879295e
add supervisor to down
hubertdeng123 8afa94e
add foreground command
hubertdeng123 725af21
uncomment dsn
hubertdeng123 4394c3c
add case to not allow bringing up supervisor programs from outside th…
hubertdeng123 907e81c
Merge branch 'hubertdeng123/add-supervisor-to-up' into hubertdeng123/…
hubertdeng123 f58475d
Merge branch 'hubertdeng123/add-supervisor-to-down' into hubertdeng12…
hubertdeng123 cc65104
merge main
hubertdeng123 a3605bc
address some feedback
hubertdeng123 37aa337
use color constants
hubertdeng123 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| from __future__ import annotations | ||
|
|
||
| import os | ||
| import pty | ||
| import shlex | ||
| from argparse import _SubParsersAction | ||
| from argparse import ArgumentParser | ||
| from argparse import Namespace | ||
|
|
||
| from sentry_sdk import capture_exception | ||
|
|
||
| from devservices.constants import DependencyType | ||
| from devservices.constants import DEVSERVICES_DIR_NAME | ||
| from devservices.constants import PROGRAMS_CONF_FILE_NAME | ||
| from devservices.exceptions import ConfigError | ||
| from devservices.exceptions import ConfigNotFoundError | ||
| from devservices.exceptions import ServiceNotFoundError | ||
| from devservices.exceptions import SupervisorConfigError | ||
| from devservices.exceptions import SupervisorProcessError | ||
| from devservices.utils.console import Console | ||
| from devservices.utils.services import find_matching_service | ||
| from devservices.utils.state import State | ||
| from devservices.utils.state import StateTables | ||
| from devservices.utils.supervisor import SupervisorManager | ||
|
|
||
|
|
||
| def add_parser(subparsers: _SubParsersAction[ArgumentParser]) -> None: | ||
| parser = subparsers.add_parser( | ||
| "foreground", help="Run a service's program in the foreground" | ||
| ) | ||
| parser.add_argument( | ||
| "program_name", help="Name of the program to run in the foreground" | ||
| ) | ||
| parser.set_defaults(func=foreground) | ||
|
|
||
|
|
||
| def foreground(args: Namespace) -> None: | ||
| """Run a service's program in the foreground.""" | ||
| console = Console() | ||
| program_name = args.program_name | ||
| try: | ||
| service = find_matching_service() | ||
| except ConfigNotFoundError as e: | ||
| capture_exception(e, level="info") | ||
| console.failure( | ||
| f"{str(e)}. Please specify a service (i.e. `devservices down sentry`) or run the command from a directory with a devservices configuration." | ||
| ) | ||
| exit(1) | ||
| except ConfigError as e: | ||
| capture_exception(e) | ||
| console.failure(str(e)) | ||
| exit(1) | ||
| except ServiceNotFoundError as e: | ||
| console.failure(str(e)) | ||
| exit(1) | ||
| modes = service.config.modes | ||
| if program_name not in service.config.dependencies: | ||
| console.failure( | ||
| f"Program {program_name} does not exist in the service's config" | ||
| ) | ||
| return | ||
| state = State() | ||
| starting_services = set(state.get_service_entries(StateTables.STARTING_SERVICES)) | ||
| started_services = set(state.get_service_entries(StateTables.STARTED_SERVICES)) | ||
| active_services = starting_services.union(started_services) | ||
| if service.name not in active_services: | ||
| console.warning(f"{service.name} is not running") | ||
| return | ||
| active_starting_modes = state.get_active_modes_for_service( | ||
| service.name, StateTables.STARTING_SERVICES | ||
| ) | ||
| active_started_modes = state.get_active_modes_for_service( | ||
| service.name, StateTables.STARTED_SERVICES | ||
| ) | ||
| active_modes = active_starting_modes or active_started_modes | ||
| mode_dependencies = set() | ||
| for active_mode in active_modes: | ||
| active_mode_dependencies = modes.get(active_mode, []) | ||
| mode_dependencies.update(active_mode_dependencies) | ||
|
|
||
| supervisor_programs = [ | ||
| dep | ||
| for dep in mode_dependencies | ||
| if dep in service.config.dependencies | ||
| and service.config.dependencies[dep].dependency_type | ||
| == DependencyType.SUPERVISOR | ||
| ] | ||
|
|
||
| if program_name not in supervisor_programs: | ||
| console.failure( | ||
| f"Program {program_name} is not running in any active modes of {service.name}" | ||
| ) | ||
| return | ||
|
|
||
| programs_config_path = os.path.join( | ||
| service.repo_path, f"{DEVSERVICES_DIR_NAME}/{PROGRAMS_CONF_FILE_NAME}" | ||
| ) | ||
|
|
||
| manager = SupervisorManager( | ||
| programs_config_path, | ||
| service_name=service.name, | ||
| ) | ||
|
|
||
| try: | ||
| program_command = manager.get_program_command(program_name) | ||
| except SupervisorConfigError as e: | ||
| capture_exception(e, level="info") | ||
| console.failure(f"Error when getting program command: {str(e)}") | ||
| return | ||
|
|
||
| try: | ||
| # Stop the supervisor process before running in foreground | ||
| console.info(f"Stopping {program_name} in supervisor") | ||
| manager.stop_process(program_name) | ||
| console.info(f"Starting {program_name} in foreground") | ||
| argv = shlex.split(program_command) | ||
|
|
||
| # Run the process in foreground | ||
| pty.spawn(argv) | ||
|
|
||
| except SupervisorProcessError as e: | ||
| capture_exception(e) | ||
| console.failure(f"Error stopping {program_name} in supervisor: {str(e)}") | ||
| except (OSError, FileNotFoundError, PermissionError) as e: | ||
| capture_exception(e) | ||
| console.failure(f"Error running {program_name} in foreground: {str(e)}") | ||
|
|
||
| try: | ||
| console.info(f"Restarting {program_name} in background") | ||
| manager.start_process(program_name) | ||
| except SupervisorProcessError as e: | ||
| capture_exception(e) | ||
| console.failure(f"Error restarting {program_name} in background: {str(e)}") | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.