diff options
Diffstat (limited to 'gitautodeploy')
-rw-r--r-- | gitautodeploy/cli/config.py | 71 | ||||
-rw-r--r-- | gitautodeploy/gitautodeploy.py | 57 | ||||
-rw-r--r-- | gitautodeploy/wrappers/git.py | 4 | ||||
-rw-r--r-- | gitautodeploy/wrappers/process.py | 11 |
4 files changed, 106 insertions, 37 deletions
diff --git a/gitautodeploy/cli/config.py b/gitautodeploy/cli/config.py index c4a6314..6b21d20 100644 --- a/gitautodeploy/cli/config.py +++ b/gitautodeploy/cli/config.py @@ -7,7 +7,8 @@ def get_config_defaults(): config['config'] = None config['ssh-keyscan'] = False config['ssl'] = False - config['ssl-pem-file'] = '~/.gitautodeploy.pem' + config['ssl-key'] = None # If specific, holds the private key + config['ssl-cert'] = '~/cert.pem' # Holds either only the public or both the private and public keys config['pidfilepath'] = '~/.gitautodeploy.pid' config['logfilepath'] = None config['host'] = '0.0.0.0' @@ -29,10 +30,20 @@ def get_config_defaults(): config['web-ui-enabled'] = False config['web-ui-whitelist'] = ['127.0.0.1'] config['web-ui-web-socket-host'] = '0.0.0.0' - config['web-ui-web-socket-port'] = 9000 + config['web-ui-web-socket-port'] = 9001 return config + +def rename_legacy_attribute_names(config): + + if 'ssl-pem-file' in config: + config['ssl-cert'] = config['ssl-pem-file'] + del config['ssl-pem-file'] + + return config + + def get_config_from_environment(): """Get configuration values provided as environment variables.""" import os @@ -54,8 +65,8 @@ def get_config_from_environment(): if 'GAD_SSL' in os.environ: config['ssl'] = True - if 'GADGAD_SSL_PEM_FILE_SSL' in os.environ: - config['ssl-pem-file'] = os.environ['GAD_SSL_PEM_FILE'] + if 'GAD_SSL_CERT' in os.environ: + config['ssl-cert'] = os.environ['GAD_SSL_CERT'] if 'GAD_PID_FILE' in os.environ: config['pidfilepath'] = os.environ['GAD_PID_FILE'] @@ -112,23 +123,33 @@ def get_config_from_argv(argv): type=str) parser.add_argument("--host", - help="address to bind to", + help="address to bind http server to", dest="host", type=str) parser.add_argument("--port", - help="port to bind to", + help="port to bind http server to", dest="port", type=int) + parser.add_argument("--ws-port", + help="port to bind web socket server to", + dest="web-ui-web-socket-port", + type=int) + parser.add_argument("--ssl", help="use ssl", dest="ssl", action="store_true") - parser.add_argument("--ssl-pem", - help="path to ssl pem file", - dest="ssl-pem", + parser.add_argument("--ssl-key", + help="path to ssl key file", + dest="ssl-key", + type=str) + + parser.add_argument("--ssl-cert", + help="path to ssl cert file", + dest="ssl-cert", type=str) config = vars(parser.parse_args(argv)) @@ -237,6 +258,12 @@ def init_config(config): if 'logfilepath' in config and config['logfilepath']: config['logfilepath'] = os.path.expanduser(config['logfilepath']) + if 'ssl-cert' in config and config['ssl-cert']: + config['ssl-cert'] = os.path.expanduser(config['ssl-cert']) + + if 'ssl-key' in config and config['ssl-key']: + config['ssl-key'] = os.path.expanduser(config['ssl-key']) + if 'repositories' not in config: config['repositories'] = [] @@ -307,6 +334,7 @@ def init_config(config): return config + def get_repo_config_from_environment(): """Look for repository config in any defined environment variables. If found, import to main config.""" @@ -337,3 +365,28 @@ def get_repo_config_from_environment(): repo_config['deploy'] = os.environ['GAD_REPO_DEPLOY'] return repo_config + + +def get_config_file_path(env_config, argv_config, search_target): + import os + + # Config file path provided in argument vector? + if 'config' in argv_config and argv_config['config']: + config_file_path = os.path.realpath(argv_config['config']) + + # Config file path provided in environment variable? + elif 'config' in env_config and env_config['config']: + config_file_path = os.path.realpath(env_config['config']) + + # Search file system + else: + + # Directories to scan for config files + target_directories = [ + os.getcwd(), # cwd + search_target # script path + ] + + config_file_path = find_config_file(target_directories) + + return config_file_path
\ No newline at end of file diff --git a/gitautodeploy/gitautodeploy.py b/gitautodeploy/gitautodeploy.py index 12b2da3..49526e8 100644 --- a/gitautodeploy/gitautodeploy.py +++ b/gitautodeploy/gitautodeploy.py @@ -290,20 +290,26 @@ class GitAutoDeploy(object): WebhookRequestHandler) # Setup SSL for HTTP server + scheme = 'HTTP' if 'ssl' in self._config and self._config['ssl']: - import ssl - logger.info("enabling ssl") - self._http_server.socket = ssl.wrap_socket(self._http_server.socket, - certfile=os.path.expanduser(self._config['ssl-pem']), - server_side=True) + if not os.path.isfile(self._config['ssl-cert']): + self._startup_event.log_critical("Unable to enable SSL: File does not exist: %s" % self._config['ssl-cert']) + else: + import ssl + self._startup_event.log_info("Enabling SSL on TCP socket for HTTP server") + scheme = 'HTTPS' + self._http_server.socket = ssl.wrap_socket(self._http_server.socket, + keyfile=self._config['ssl-key'], + certfile=self._config['ssl-cert'], + server_side=True) sa = self._http_server.socket.getsockname() - self._startup_event.log_info("Listening for http connections on %s port %s" % (sa[0], sa[1])) + self._startup_event.log_info("Listening for %s connections on %s port %s" % (scheme, sa[0], sa[1])) self._startup_event.http_address = sa[0] self._startup_event.http_port = sa[1] self._startup_event.set_http_started(True) except socket.error as e: - self._startup_event.log_critical("Error on socket: %s" % e) + self._startup_event.log_critical("Unable to start http server: %s" % e) sys.exit(1) # Run forever @@ -336,6 +342,7 @@ class GitAutoDeploy(object): import sys from autobahn.websocket import WebSocketServerProtocol, WebSocketServerFactory from twisted.internet import reactor + from twisted.internet.error import BindError # Create a WebSocketClientHandler instance WebSocketClientHandler = WebSocketClientHandlerFactory(self._config, self._ws_clients, self._event_store) @@ -356,6 +363,9 @@ class GitAutoDeploy(object): # Serve forever (until reactor.stop()) reactor.run(installSignalHandlers=False) + except BindError as e: + self._startup_event.log_critical("Unable to start web socket server: %s" % e) + except ImportError: self._startup_event.log_error("Unable to start web socket server due to missing dependency.") @@ -462,12 +472,14 @@ class GitAutoDeploy(object): sys.stdout = self._default_stdout sys.stderr = self._default_stderr - #sys.exit(0) def main(): import signal from gitautodeploy import GitAutoDeploy - from cli.config import get_config_defaults, get_config_from_environment, get_config_from_argv, find_config_file, get_config_from_file, get_repo_config_from_environment, init_config + from cli.config import get_config_defaults, get_config_from_environment + from cli.config import get_config_from_argv, find_config_file + from cli.config import get_config_from_file, get_repo_config_from_environment + from cli.config import init_config, get_config_file_path, rename_legacy_attribute_names import sys import os @@ -482,35 +494,32 @@ def main(): if hasattr(signal, 'SIGPIPE') and hasattr(signal, 'SIG_IGN'): signal.signal(signal.SIGPIPE, signal.SIG_IGN) + # Get default config values config = get_config_defaults() # Get config values from environment variables and commadn line arguments environment_config = get_config_from_environment() argv_config = get_config_from_argv(sys.argv[1:]) - # Merge config values + # Merge config values from environment variables config.update(environment_config) - config.update(argv_config) - - # Config file path provided? - if 'config' in config and config['config']: - config_file_path = os.path.realpath(config['config']) - - else: - - # Directories to scan for config files - target_directories = [ - os.getcwd(), # cwd - os.path.dirname(os.path.realpath(__file__)) # script path - ] - config_file_path = find_config_file(target_directories) + search_target = os.path.dirname(os.path.realpath(__file__)) + config_file_path = get_config_file_path(environment_config, argv_config, search_target) # Config file path provided or found? if config_file_path: file_config = get_config_from_file(config_file_path) + + # Merge config values from config file (overrides environment variables) config.update(file_config) + # Merge config value from command line (overrides environment variables and config file) + config.update(argv_config) + + # Rename legacy config option names + config = rename_legacy_attribute_names(config) + # Extend config data with any repository defined by environment variables repo_config = get_repo_config_from_environment() diff --git a/gitautodeploy/wrappers/git.py b/gitautodeploy/wrappers/git.py index 1f7fe23..3b347d3 100644 --- a/gitautodeploy/wrappers/git.py +++ b/gitautodeploy/wrappers/git.py @@ -32,7 +32,7 @@ class GitWrapper(): # All commands need to success for command in commands: - res = ProcessWrapper().call(command, cwd=repo_config['path'], shell=True) + res = ProcessWrapper().call(command, cwd=repo_config['path'], shell=True, supressStderr=True) if res != 0: logger.error("Command '%s' failed with exit code %s" % (command, res)) @@ -76,7 +76,7 @@ class GitWrapper(): # All commands need to success for command in commands: - res = ProcessWrapper().call(command, cwd=repo_config['path'], shell=True) + res = ProcessWrapper().call(command, cwd=repo_config['path'], shell=True, supressStderr=True) if res != 0: logger.error("Command '%s' failed with exit code %s" % (command, res)) diff --git a/gitautodeploy/wrappers/process.py b/gitautodeploy/wrappers/process.py index 867e6cf..a810f23 100644 --- a/gitautodeploy/wrappers/process.py +++ b/gitautodeploy/wrappers/process.py @@ -9,7 +9,7 @@ class ProcessWrapper(): """Run command with arguments. Wait for command to complete. Sends output to logging module. The arguments are the same as for the Popen constructor.""" - + from subprocess import Popen, PIPE import logging logger = logging.getLogger() @@ -17,6 +17,10 @@ class ProcessWrapper(): kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE + if 'supressStderr' in kwargs: + supressStderr = kwargs['supressStderr'] + del kwargs['supressStderr'] + p = Popen(*popenargs, **kwargs) stdout, stderr = p.communicate() @@ -30,6 +34,9 @@ class ProcessWrapper(): if stderr: for line in stderr.strip().split("\n"): - logger.error(line) + if supressStderr: + logger.info(line) + else: + logger.error(line) return p.returncode
\ No newline at end of file |