Rework logging and execution
It is now possible to run adlermanager with: python -m adlermanager While there we improve logging.
This commit is contained in:
parent
1a44337ded
commit
45ed9bbed7
|
@ -70,10 +70,14 @@ And give yourself access to the given site, by adding your username to its
|
|||
|
||||
### Running
|
||||
|
||||
To run the server for development you can use the following command:
|
||||
To run the server for development you can one of the following commands:
|
||||
|
||||
```sh
|
||||
# Using twistd
|
||||
# https://docs.twisted.org/en/stable/core/howto/basics.html#twistd
|
||||
pipenv run twistd -ny app.py
|
||||
# Running as a module
|
||||
python -m adlermanager
|
||||
```
|
||||
|
||||
And for deployment, you can use [`twistd`][twistd] itself to run the process
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import functools
|
||||
import json
|
||||
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
|
||||
|
||||
import attr
|
||||
import yaml
|
||||
from twisted.logger import Logger
|
||||
from twisted.python.filepath import FilePath
|
||||
|
||||
from .conch_helpers import SSHSimpleAvatar, SSHSimpleProtocol
|
||||
|
@ -12,6 +12,8 @@ from .model import SiteConfig
|
|||
if TYPE_CHECKING:
|
||||
from adlermanager.SitesManager import SiteManager, SitesManager
|
||||
|
||||
log = Logger()
|
||||
|
||||
|
||||
class AdlerManagerSSHProtocol(SSHSimpleProtocol):
|
||||
sites_manager: "SitesManager"
|
||||
|
@ -21,8 +23,7 @@ class AdlerManagerSSHProtocol(SSHSimpleProtocol):
|
|||
Create an instance of AdlerManagerSSHProtocol.
|
||||
"""
|
||||
SSHSimpleProtocol.__init__(self, user)
|
||||
|
||||
# TODO: Do stuff like getting user sites, showing alert warnings, etc.
|
||||
log.info("SSH login for {user}", user=user.username)
|
||||
|
||||
def do_list_sites(self) -> None:
|
||||
"""
|
||||
|
@ -95,22 +96,13 @@ class AdlerManagerSSHProtocol(SSHSimpleProtocol):
|
|||
sm.site_config = sc
|
||||
sm.config_file.setContent(sc.to_YAML().encode("utf-8"))
|
||||
sm.config_file.chmod(0o640)
|
||||
log.info(
|
||||
"User {user} changed {site} config", user=self.user.username, site=site
|
||||
)
|
||||
if self.interactive:
|
||||
self.terminal_write("Persisted SiteConfiguration")
|
||||
self.terminal.nextLine()
|
||||
|
||||
def do_tmp_dump_state(self) -> None:
|
||||
"""
|
||||
This command is temporary and just dumps all known state.
|
||||
"""
|
||||
for k, sm in self.sites_manager.get_user_sites(self.user.username).items():
|
||||
self.terminal_write(f"\n#\n# {k}\n#\n")
|
||||
for _, srv in sm.service_managers.items():
|
||||
self.terminal_write(f"## {srv.label}\n")
|
||||
self.terminal_write(json.dumps(srv.components))
|
||||
self.terminal.nextLine()
|
||||
self.terminal.nextLine()
|
||||
|
||||
@functools.lru_cache() # we don't need to re-read every time
|
||||
def motd(self) -> Union[str, bytes]:
|
||||
custom_motd = FilePath(self.sites_manager.global_config.data_dir).child(
|
||||
|
|
|
@ -17,10 +17,20 @@ class SitesManager(object):
|
|||
global_config: ConfigClass = attr.ib()
|
||||
site_managers: Dict[str, "SiteManager"] = attr.ib(factory=dict)
|
||||
tokens: Dict[str, "SiteManager"] = attr.ib(factory=dict)
|
||||
|
||||
log = Logger()
|
||||
log: Logger = attr.ib(factory=Logger)
|
||||
|
||||
def __attrs_post_init__(self) -> None:
|
||||
def startup_message() -> None:
|
||||
self.log.info(
|
||||
f"Starting server with this configuration:\n{self.global_config}",
|
||||
system=SitesManager.__name__,
|
||||
)
|
||||
|
||||
# Inform people of current configuration when reactor starts
|
||||
_ = task.deferLater(reactor, 0, startup_message).addErrback( # type: ignore
|
||||
default_errback
|
||||
)
|
||||
# Load data
|
||||
self.reload()
|
||||
|
||||
def reload(self) -> "SitesManager":
|
||||
|
@ -79,7 +89,6 @@ class SiteManager(object):
|
|||
path: FilePath = attr.ib()
|
||||
tokens: List[str] = attr.ib(factory=list)
|
||||
ssh_users: List[str] = attr.ib(factory=list)
|
||||
log = Logger()
|
||||
monitoring_is_down: bool = attr.ib(default=False)
|
||||
definition: Dict[str, Any] = attr.ib(factory=dict)
|
||||
title: str = attr.ib(default="")
|
||||
|
@ -92,10 +101,12 @@ class SiteManager(object):
|
|||
# Default to 2 mins
|
||||
_timeout_seconds = 2 * 60
|
||||
|
||||
def __attrs_post_init__(self) -> None:
|
||||
self.reload(first_run=True)
|
||||
log: Logger = attr.ib(factory=Logger)
|
||||
|
||||
def reload(self, first_run: bool = False) -> "SiteManager":
|
||||
def __attrs_post_init__(self) -> None:
|
||||
self.reload()
|
||||
|
||||
def reload(self) -> "SiteManager":
|
||||
self.load_definition()
|
||||
self.title = self.definition["title"]
|
||||
self.load_tokens()
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
from typing import Any, Dict, Generator, Union, cast
|
||||
|
||||
from twisted.internet import defer
|
||||
from twisted.logger import Logger
|
||||
from twisted.web import resource, server
|
||||
from twisted.web._responses import INTERNAL_SERVER_ERROR, OK, UNAUTHORIZED
|
||||
from twisted.web.server import Request
|
||||
|
||||
log = Logger()
|
||||
|
||||
|
||||
class TokenResource(resource.Resource):
|
||||
"""
|
||||
|
@ -78,9 +81,8 @@ class TokenResource(resource.Resource):
|
|||
res = yield defer.maybeDeferred(self.processToken, token_data, request)
|
||||
code: int = cast(int, res)
|
||||
except Exception:
|
||||
import traceback
|
||||
log.failure("Unknown error")
|
||||
|
||||
traceback.print_stack()
|
||||
code = INTERNAL_SERVER_ERROR
|
||||
request.setResponseCode(code) # type: ignore
|
||||
defer.returnValue(code)
|
||||
|
|
|
@ -15,6 +15,8 @@ from .AdlerManagerTokenResource import AdlerManagerTokenResource
|
|||
from .Config import Config
|
||||
from .SitesManager import SiteManager, SitesManager
|
||||
|
||||
log = Logger()
|
||||
|
||||
|
||||
def get_jinja_env(supportDir: str) -> jinja2.Environment:
|
||||
"""
|
||||
|
@ -52,7 +54,6 @@ def get_jinja_env(supportDir: str) -> jinja2.Environment:
|
|||
|
||||
def web_root(sites_manager: "SitesManager") -> KleinResource:
|
||||
app = Klein()
|
||||
log = Logger()
|
||||
|
||||
@app.route("/") # type: ignore
|
||||
def index(request: Request):
|
||||
|
@ -70,9 +71,6 @@ def web_root(sites_manager: "SitesManager") -> KleinResource:
|
|||
try:
|
||||
site = sites_manager.site_managers[host]
|
||||
except Exception:
|
||||
import traceback
|
||||
|
||||
traceback.print_stack()
|
||||
log.failure("sad cat")
|
||||
return resource.ErrorPage(
|
||||
500, "Sad cat", '<a href="http://http.cat/500">http://http.cat/500</a>'
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Run in foreground using:
|
||||
- a generic service manager: python -m adlermanager
|
||||
- twistd: twistd -ny src/adlermanager/__main__.py
|
||||
"""
|
||||
|
||||
# Run with twistd -ny app.py
|
||||
from typing import Iterable, cast
|
||||
|
||||
from twisted.application import service, strports
|
||||
from twisted.logger import Logger
|
||||
from twisted.python.filepath import FilePath
|
||||
from twisted.web import server
|
||||
|
||||
|
@ -38,6 +42,26 @@ if Config.ssh_enabled:
|
|||
)
|
||||
i.setServiceParent(serv_collection) # type: ignore
|
||||
|
||||
# Inform people of current configuration
|
||||
log = Logger()
|
||||
log.info(f"Starting server with this configuration:\n{Config}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
from twisted import logger
|
||||
|
||||
# Setup global logging to stdout
|
||||
logger.globalLogPublisher.addObserver(
|
||||
cast(logger.ILogObserver, logger.textFileLogObserver(sys.stdout))
|
||||
)
|
||||
|
||||
# Run without twistd as documented upstream:
|
||||
# https://docs.twisted.org/en/stable/core/howto/basics.html#twistd
|
||||
from twisted.internet import reactor as _reactor # type: ignore
|
||||
from twisted.internet.base import ReactorBase
|
||||
|
||||
reactor = cast(ReactorBase, _reactor)
|
||||
for srv in cast(Iterable[service.IService], serv_collection):
|
||||
srv.startService()
|
||||
reactor.addSystemEventTrigger("before", "shutdown", srv.stopService)
|
||||
|
||||
# Finally, start the reactor
|
||||
reactor.run()
|
Loading…
Reference in a new issue