summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--docs/Start automatically on boot.md4
-rw-r--r--gitautodeploy/__init__.py7
-rw-r--r--gitautodeploy/__main__.py2
-rw-r--r--gitautodeploy/cli/__init__.py2
-rw-r--r--gitautodeploy/events.py5
-rw-r--r--gitautodeploy/gitautodeploy.py44
-rw-r--r--gitautodeploy/httpserver.py68
-rw-r--r--gitautodeploy/parsers/__init__.py12
-rw-r--r--gitautodeploy/parsers/bitbucket.py2
-rw-r--r--gitautodeploy/parsers/coding.py2
-rw-r--r--gitautodeploy/parsers/generic.py2
-rw-r--r--gitautodeploy/parsers/github.py2
-rw-r--r--gitautodeploy/parsers/gitlab.py2
-rw-r--r--gitautodeploy/parsers/gitlabci.py2
-rw-r--r--gitautodeploy/wrappers/__init__.py4
-rw-r--r--gitautodeploy/wrappers/git.py8
-rw-r--r--gitautodeploy/wrappers/process.py4
-rwxr-xr-xplatforms/linux/initfiles/debianLSBInitScripts/git-auto-deploy2
-rw-r--r--platforms/linux/initfiles/systemd/git-auto-deploy.service2
20 files changed, 96 insertions, 84 deletions
diff --git a/README.md b/README.md
index 8330b34..22438d5 100644
--- a/README.md
+++ b/README.md
@@ -67,11 +67,11 @@ Copy of the sample config and modify it. [Read more about the configuration opti
Start ```Git-Auto-Deploy``` manually using;
- python gitautodeploy --config config.json
+ python -m gitautodeploy --config config.json
To start ```Git-Auto-Deploy``` automatically on boot, open crontab in edit mode using ```crontab -e``` and add the entry below.
- @reboot /usr/bin/python /path/to/Git-Auto-Deploy/gitautodeploy --daemon-mode --quiet --config /path/to/git-auto-deploy.conf.json
+ @reboot /usr/bin/python -m /path/to/Git-Auto-Deploy/gitautodeploy --daemon-mode --quiet --config /path/to/git-auto-deploy.conf.json
You can also configure ```Git-Auto-Deploy``` to start on boot using a init.d-script (for Debian and Sys-V like init systems) or a service for systemd. [Read more about starting Git-Auto-Deploy automatically using init.d or systemd](./docs/Start automatically on boot.md).
diff --git a/docs/Start automatically on boot.md b/docs/Start automatically on boot.md
index f0f3ffb..30d5702 100644
--- a/docs/Start automatically on boot.md
+++ b/docs/Start automatically on boot.md
@@ -2,14 +2,14 @@
```Git-Auto-Deploy``` can be automatically started at boot time using various techniques. Below you'll find a couple of suggested approaches with instructions.
-The following instructions assumes that you are running ```Git-Auto-Deploy``` from a clone of this repository. In such a case, ```Git-Auto-Deploy``` is started by invoking ```python``` and referencing the ```gitautodeploy``` python module which is found in the cloned repository. Such a command can look like ```python /path/to/Git-Auto-Deploy/gitautodeploy --daemon-mode```.
+The following instructions assumes that you are running ```Git-Auto-Deploy``` from a clone of this repository. In such a case, ```Git-Auto-Deploy``` is started by invoking ```python -m``` and referencing the ```gitautodeploy``` python module which is found in the cloned repository. Such a command can look like ```python -m /path/to/Git-Auto-Deploy/gitautodeploy --daemon-mode```.
If you have used any of the alternative installation methods (install with pip or as a debian package), you will instead start ```Git-Auto-Deploy``` using a installed executable. ```Git-Auto-Deploy``` would then be started using a command like ```git-auto-deploy --daemon-mode``` instead. If you have installed ```Git-Auto-Deploy``` in this way, you will need to modify the paths and commands used in the instructions below.
## Crontab
The easiest way to configure your system to automatically start ```Git-Auto-Deploy``` after a reboot is using crontab. Open crontab in edit mode using ```crontab -e``` and add the following:
- @reboot /usr/bin/python /path/to/Git-Auto-Deploy/gitautodeploy --daemon-mode --quiet
+ @reboot /usr/bin/python -m /path/to/Git-Auto-Deploy/gitautodeploy --daemon-mode --quiet
## Debian and Sys-V like init system.
diff --git a/gitautodeploy/__init__.py b/gitautodeploy/__init__.py
index c8a461c..8f762c3 100644
--- a/gitautodeploy/__init__.py
+++ b/gitautodeploy/__init__.py
@@ -1,5 +1,2 @@
-from wrappers import *
-from lock import *
-from parsers import *
-from gitautodeploy import *
-from cli import * \ No newline at end of file
+from .gitautodeploy import *
+from .cli import * \ No newline at end of file
diff --git a/gitautodeploy/__main__.py b/gitautodeploy/__main__.py
index f97e44f..0070f6a 100644
--- a/gitautodeploy/__main__.py
+++ b/gitautodeploy/__main__.py
@@ -2,4 +2,6 @@
from gitautodeploy import main
if __name__ == '__main__':
+ import sys, os
+ sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
main()
diff --git a/gitautodeploy/cli/__init__.py b/gitautodeploy/cli/__init__.py
index 1725ebe..27c9ec6 100644
--- a/gitautodeploy/cli/__init__.py
+++ b/gitautodeploy/cli/__init__.py
@@ -1 +1 @@
-from config import *
+from .config import *
diff --git a/gitautodeploy/events.py b/gitautodeploy/events.py
index 777055a..cf777a6 100644
--- a/gitautodeploy/events.py
+++ b/gitautodeploy/events.py
@@ -148,4 +148,7 @@ class EventStore(object):
self.update_observers(action, message)
def dict_repr(self):
- return map(lambda x: x.dict_repr(), self.actions)
+ action_repr = []
+ for action in self.actions:
+ action_repr.append(action.dict_repr())
+ return action_repr
diff --git a/gitautodeploy/gitautodeploy.py b/gitautodeploy/gitautodeploy.py
index cadadd1..c7ebf3a 100644
--- a/gitautodeploy/gitautodeploy.py
+++ b/gitautodeploy/gitautodeploy.py
@@ -11,6 +11,8 @@ class LogInterface(object):
for line in msg.strip().split("\n"):
self.level(line)
+ def flush(self):
+ pass
class GitAutoDeploy(object):
_instance = None
@@ -32,7 +34,7 @@ class GitAutoDeploy(object):
return cls._instance
def __init__(self):
- from events import EventStore, StartupEvent
+ from .events import EventStore, StartupEvent
# Setup an event store instance that can keep a global record of events
self._event_store = EventStore()
@@ -48,7 +50,7 @@ class GitAutoDeploy(object):
import os
import re
import logging
- from wrappers import GitWrapper
+ from .wrappers import GitWrapper
logger = logging.getLogger()
if not 'repositories' in self._config:
@@ -76,7 +78,7 @@ class GitAutoDeploy(object):
def ssh_key_scan(self):
import re
import logging
- from wrappers import ProcessWrapper
+ from .wrappers import ProcessWrapper
logger = logging.getLogger()
for repository in self._config['repositories']:
@@ -113,7 +115,7 @@ class GitAutoDeploy(object):
if 'pidfilepath' in self._config and self._config['pidfilepath']:
try:
os.remove(self._config['pidfilepath'])
- except OSError, e:
+ except OSError as e:
if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
raise
@@ -124,7 +126,7 @@ class GitAutoDeploy(object):
try:
# Spawn first child. Returns 0 in the child and pid in the parent.
pid = os.fork()
- except OSError, e:
+ except OSError as e:
raise Exception("%s [%d]" % (e.strerror, e.errno))
# First child
@@ -135,7 +137,7 @@ class GitAutoDeploy(object):
# Spawn second child
pid = os.fork()
- except OSError, e:
+ except OSError as e:
raise Exception("%s [%d]" % (e.strerror, e.errno))
if pid == 0:
@@ -155,12 +157,16 @@ class GitAutoDeploy(object):
def setup(self, config):
"""Setup an instance of GAD based on the provided config object."""
import sys
- from BaseHTTPServer import HTTPServer
import socket
import os
import logging
- from lock import Lock
- from httpserver import WebhookRequestHandlerFactory
+ from .lock import Lock
+ from .httpserver import WebhookRequestHandlerFactory
+
+ try:
+ from BaseHTTPServer import HTTPServer
+ except ImportError as e:
+ from http.server import HTTPServer
# This solves https://github.com/olipo186/Git-Auto-Deploy/issues/118
try:
@@ -262,7 +268,7 @@ class GitAutoDeploy(object):
# sa = self._ws_server.socket.getsockname()
# self._startup_event.log_info("Listening for web socket on %s port %s" % (sa[0], sa[1]))
- # except ImportError, e:
+ # except ImportError as e:
# self._startup_event.log_error("Unable to start web socket server due to a too old version of Python. Version => 2.7.9 is required.")
# Setup SSL for HTTP server
@@ -281,7 +287,7 @@ class GitAutoDeploy(object):
# Actual port bound to (nessecary when OS picks randomly free port)
self._port = sa[1]
- except socket.error, e:
+ except socket.error as e:
self._startup_event.log_critical("Error on socket: %s" % e)
sys.exit(1)
@@ -290,18 +296,18 @@ class GitAutoDeploy(object):
import socket
import logging
import os
- from events import SystemEvent
+ from .events import SystemEvent
try:
self._http_server.serve_forever()
- except socket.error, e:
+ except socket.error as e:
event = SystemEvent()
self._event_store.register_action(event)
event.log_critical("Error on socket: %s" % e)
sys.exit(1)
- except KeyboardInterrupt, e:
+ except KeyboardInterrupt as e:
event = SystemEvent()
self._event_store.register_action(event)
event.log_info('Requested close by keyboard interrupt signal')
@@ -321,7 +327,7 @@ class GitAutoDeploy(object):
import socket
import logging
import os
- from events import SystemEvent
+ from .events import SystemEvent
import threading
# Add script dir to sys path, allowing us to import sub modules even after changing cwd
@@ -353,18 +359,18 @@ class GitAutoDeploy(object):
"""Start listening for incoming requests."""
import sys
import socket
- from events import SystemEvent
+ from .events import SystemEvent
try:
self._http_server.handle_request()
- except socket.error, e:
+ except socket.error as e:
event = SystemEvent()
self._event_store.register_action(event)
event.log_critical("Error on socket: %s" % e)
sys.exit(1)
- except KeyboardInterrupt, e:
+ except KeyboardInterrupt as e:
event = SystemEvent()
self._event_store.register_action(event)
event.log_info('Requested close by keyboard interrupt signal')
@@ -372,7 +378,7 @@ class GitAutoDeploy(object):
self.exit()
def signal_handler(self, signum, frame):
- from events import SystemEvent
+ from .events import SystemEvent
self.stop()
event = SystemEvent()
diff --git a/gitautodeploy/httpserver.py b/gitautodeploy/httpserver.py
index 8efcf9b..5a06498 100644
--- a/gitautodeploy/httpserver.py
+++ b/gitautodeploy/httpserver.py
@@ -1,13 +1,12 @@
+from .parsers import CodingRequestParser, GitLabCIRequestParser, GitLabRequestParser, GitHubRequestParser, BitBucketRequestParser, GenericRequestParser
+
class WebbhookRequestProcessor(object):
def get_service_handler(self, request_headers, request_body, action):
"""Parses the incoming request and attempts to determine whether
it originates from GitHub, GitLab or any other known service."""
import json
- import logging
- import parsers
- logger = logging.getLogger()
payload = json.loads(request_body)
if not isinstance(payload, dict):
@@ -18,33 +17,33 @@ class WebbhookRequestProcessor(object):
# Assume Coding if the X-Coding-Event HTTP header is set
if 'x-coding-event' in request_headers:
- return parsers.CodingRequestParser
+ return CodingRequestParser
# Assume GitLab if the X-Gitlab-Event HTTP header is set
elif 'x-gitlab-event' in request_headers:
# Special Case for Gitlab CI
if content_type == "application/json" and "build_status" in payload:
- return parsers.GitLabCIRequestParser
+ return GitLabCIRequestParser
else:
- return parsers.GitLabRequestParser
+ return GitLabRequestParser
# Assume GitHub if the X-GitHub-Event HTTP header is set
elif 'x-github-event' in request_headers:
- return parsers.GitHubRequestParser
+ return GitHubRequestParser
# Assume BitBucket if the User-Agent HTTP header is set to
# 'Bitbucket-Webhooks/2.0' (or something similar)
elif user_agent and user_agent.lower().find('bitbucket') != -1:
- return parsers.BitBucketRequestParser
+ return BitBucketRequestParser
# This handles old GitLab requests and Gogs requests for example.
elif content_type == "application/json":
action.log_info("Received event from unknown origin.")
- return parsers.GenericRequestParser
+ return GenericRequestParser
action.log_error("Unable to recognize request origin. Don't know how to handle the request.")
return
@@ -55,8 +54,8 @@ class WebbhookRequestProcessor(object):
import os
import time
import logging
- from wrappers import GitWrapper
- from lock import Lock
+ from .wrappers import GitWrapper
+ from .lock import Lock
import json
logger = logging.getLogger()
@@ -143,6 +142,10 @@ class WebbhookRequestProcessor(object):
result.append(repo_result)
+ action.log_info("Deploy commands were executed")
+ action.set_success(True)
+ action.update()
+
return result
@@ -157,7 +160,7 @@ class WebhookRequestFilter(object):
for filter in payload_filters:
# All options specified in the filter must match
- for filter_key, filter_value in filter.iteritems():
+ for filter_key, filter_value in filter.items():
# Ignore filters with value None (let them pass)
if filter_value == None:
@@ -221,8 +224,8 @@ class WebhookRequestFilter(object):
import os
import time
import logging
- from wrappers import GitWrapper
- from lock import Lock
+ from .wrappers import GitWrapper
+ from .lock import Lock
import json
logger = logging.getLogger()
@@ -252,7 +255,10 @@ class WebhookRequestFilter(object):
def WebhookRequestHandlerFactory(config, event_store):
"""Factory method for webhook request handler class"""
- from SimpleHTTPServer import SimpleHTTPRequestHandler
+ try:
+ from SimpleHTTPServer import SimpleHTTPRequestHandler
+ except ImportError as e:
+ from http.server import SimpleHTTPRequestHandler
class WebhookRequestHandler(SimpleHTTPRequestHandler, object):
"""Extends the BaseHTTPRequestHandler class and handles the incoming
@@ -288,8 +294,7 @@ def WebhookRequestHandlerFactory(config, event_store):
self.send_response(200, 'OK')
self.send_header('Content-type', 'application/json')
self.end_headers()
- self.wfile.write(json.dumps(data))
- self.wfile.close()
+ self.wfile.write(json.dumps(data).encode('utf-8'))
return
return SimpleHTTPRequestHandler.do_GET(self)
@@ -299,16 +304,17 @@ def WebhookRequestHandlerFactory(config, event_store):
from threading import Timer
import logging
import json
- from events import WebhookAction
+ from .events import WebhookAction
+ import threading
logger = logging.getLogger()
- content_length = int(self.headers.getheader('content-length'))
- request_body = self.rfile.read(content_length)
+ content_length = int(self.headers.get('content-length'))
+ request_body = self.rfile.read(content_length).decode('utf-8')
# Extract request headers and make all keys to lowercase (makes them easier to compare)
request_headers = dict(self.headers)
- request_headers = dict((k.lower(), v) for k, v in request_headers.iteritems())
+ request_headers = dict((k.lower(), v) for k, v in request_headers.items())
action = WebhookAction(self.client_address, request_headers, request_body)
action.set_waiting(True)
@@ -362,15 +368,11 @@ def WebhookRequestHandlerFactory(config, event_store):
action.log_warning("Request not valid")
return
- # Send HTTP response before the git pull and/or deploy commands?
- #if not 'detailed-response' in self._config or not self._config['detailed-response']:
+ test_case['expected']['status'] = 200
+
self.send_response(200, 'OK')
self.send_header('Content-type', 'text/plain')
self.end_headers()
- self.finish()
- self.connection.close()
-
- test_case['expected']['status'] = 200
if len(repo_configs) == 0:
action.log_info("Filter does not match")
@@ -379,7 +381,9 @@ def WebhookRequestHandlerFactory(config, event_store):
action.log_info("Executing deploy commands")
# Schedule the execution of the webhook (git pull and trigger deploy etc)
- request_processor.execute_webhook(repo_configs, request_headers, request_body, action)
+ #request_processor.execute_webhook(repo_configs, request_headers, request_body, action)
+ thread = threading.Thread(target=request_processor.execute_webhook, args=[repo_configs, request_headers, request_body, action])
+ thread.start()
# Add additional test case data
test_case['config'] = {
@@ -389,11 +393,7 @@ def WebhookRequestHandlerFactory(config, event_store):
'deploy': 'echo test!'
}
- action.log_info("Deploy commands were executed")
- action.set_success(True)
- action.update()
-
- except ValueError, e:
+ except ValueError as e:
self.send_error(400, 'Unprocessable request')
action.log_warning('Unable to process incoming request from %s:%s' % (self.client_address[0], self.client_address[1]))
test_case['expected']['status'] = 400
@@ -401,7 +401,7 @@ def WebhookRequestHandlerFactory(config, event_store):
action.update()
return
- except Exception, e:
+ except Exception as e:
if 'detailed-response' in self._config and self._config['detailed-response']:
self.send_error(500, 'Unable to process request')
diff --git a/gitautodeploy/parsers/__init__.py b/gitautodeploy/parsers/__init__.py
index c993454..cecd1c7 100644
--- a/gitautodeploy/parsers/__init__.py
+++ b/gitautodeploy/parsers/__init__.py
@@ -1,6 +1,6 @@
-from bitbucket import BitBucketRequestParser
-from github import GitHubRequestParser
-from gitlab import GitLabRequestParser
-from gitlabci import GitLabCIRequestParser
-from generic import GenericRequestParser
-from coding import CodingRequestParser \ No newline at end of file
+from .bitbucket import BitBucketRequestParser
+from .github import GitHubRequestParser
+from .gitlab import GitLabRequestParser
+from .gitlabci import GitLabCIRequestParser
+from .generic import GenericRequestParser
+from .coding import CodingRequestParser \ No newline at end of file
diff --git a/gitautodeploy/parsers/bitbucket.py b/gitautodeploy/parsers/bitbucket.py
index 80899fd..b80f6aa 100644
--- a/gitautodeploy/parsers/bitbucket.py
+++ b/gitautodeploy/parsers/bitbucket.py
@@ -1,4 +1,4 @@
-from common import WebhookRequestParser
+from .common import WebhookRequestParser
class BitBucketRequestParser(WebhookRequestParser):
diff --git a/gitautodeploy/parsers/coding.py b/gitautodeploy/parsers/coding.py
index 889c3ee..3d114d4 100644
--- a/gitautodeploy/parsers/coding.py
+++ b/gitautodeploy/parsers/coding.py
@@ -1,4 +1,4 @@
-from common import WebhookRequestParser
+from .common import WebhookRequestParser
class CodingRequestParser(WebhookRequestParser):
diff --git a/gitautodeploy/parsers/generic.py b/gitautodeploy/parsers/generic.py
index a93e90b..c71bced 100644
--- a/gitautodeploy/parsers/generic.py
+++ b/gitautodeploy/parsers/generic.py
@@ -1,4 +1,4 @@
-from common import WebhookRequestParser
+from .common import WebhookRequestParser
class GenericRequestParser(WebhookRequestParser):
diff --git a/gitautodeploy/parsers/github.py b/gitautodeploy/parsers/github.py
index bede7bb..5f2ba5d 100644
--- a/gitautodeploy/parsers/github.py
+++ b/gitautodeploy/parsers/github.py
@@ -1,4 +1,4 @@
-from common import WebhookRequestParser
+from .common import WebhookRequestParser
class GitHubRequestParser(WebhookRequestParser):
diff --git a/gitautodeploy/parsers/gitlab.py b/gitautodeploy/parsers/gitlab.py
index 5d0d348..6767907 100644
--- a/gitautodeploy/parsers/gitlab.py
+++ b/gitautodeploy/parsers/gitlab.py
@@ -1,4 +1,4 @@
-from common import WebhookRequestParser
+from .common import WebhookRequestParser
class GitLabRequestParser(WebhookRequestParser):
diff --git a/gitautodeploy/parsers/gitlabci.py b/gitautodeploy/parsers/gitlabci.py
index 22af596..eebf2bd 100644
--- a/gitautodeploy/parsers/gitlabci.py
+++ b/gitautodeploy/parsers/gitlabci.py
@@ -1,4 +1,4 @@
-from common import WebhookRequestParser
+from .common import WebhookRequestParser
class GitLabCIRequestParser(WebhookRequestParser):
diff --git a/gitautodeploy/wrappers/__init__.py b/gitautodeploy/wrappers/__init__.py
index d7df44b..aad49c9 100644
--- a/gitautodeploy/wrappers/__init__.py
+++ b/gitautodeploy/wrappers/__init__.py
@@ -1,2 +1,2 @@
-from git import *
-from process import * \ No newline at end of file
+from .git import *
+from .process import * \ No newline at end of file
diff --git a/gitautodeploy/wrappers/git.py b/gitautodeploy/wrappers/git.py
index 910e9f6..1f7fe23 100644
--- a/gitautodeploy/wrappers/git.py
+++ b/gitautodeploy/wrappers/git.py
@@ -9,7 +9,7 @@ class GitWrapper():
def init(repo_config):
"""Init remote url of the repo from the git server"""
import logging
- from process import ProcessWrapper
+ from .process import ProcessWrapper
import os
import platform
@@ -49,7 +49,7 @@ class GitWrapper():
def pull(repo_config):
"""Pulls the latest version of the repo from the git server"""
import logging
- from process import ProcessWrapper
+ from .process import ProcessWrapper
import os
import platform
@@ -93,7 +93,7 @@ class GitWrapper():
def clone(repo_config):
"""Clones the latest version of the repo from the git server"""
import logging
- from process import ProcessWrapper
+ from .process import ProcessWrapper
import os
import platform
@@ -127,7 +127,7 @@ class GitWrapper():
@staticmethod
def deploy(repo_config):
"""Executes any supplied post-pull deploy command"""
- from process import ProcessWrapper
+ from .process import ProcessWrapper
import logging
logger = logging.getLogger()
diff --git a/gitautodeploy/wrappers/process.py b/gitautodeploy/wrappers/process.py
index 30adc36..867e6cf 100644
--- a/gitautodeploy/wrappers/process.py
+++ b/gitautodeploy/wrappers/process.py
@@ -20,6 +20,10 @@ class ProcessWrapper():
p = Popen(*popenargs, **kwargs)
stdout, stderr = p.communicate()
+ # Decode bytes to string (assume utf-8 encoding)
+ stdout = stdout.decode("utf-8")
+ stderr = stderr.decode("utf-8")
+
if stdout:
for line in stdout.strip().split("\n"):
logger.info(line)
diff --git a/platforms/linux/initfiles/debianLSBInitScripts/git-auto-deploy b/platforms/linux/initfiles/debianLSBInitScripts/git-auto-deploy
index 310cf07..2b357db 100755
--- a/platforms/linux/initfiles/debianLSBInitScripts/git-auto-deploy
+++ b/platforms/linux/initfiles/debianLSBInitScripts/git-auto-deploy
@@ -14,7 +14,7 @@
NAME="git-auto-deploy"
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="GitAutodeploy"
-DAEMON="/usr/bin/env python /opt/Git-Auto-Deploy/gitautodeploy"
+DAEMON="/usr/bin/env python -m /opt/Git-Auto-Deploy/gitautodeploy"
DAEMON_UID=root
DAEMON_GID=root
RUNDIR=/var/run/$NAME
diff --git a/platforms/linux/initfiles/systemd/git-auto-deploy.service b/platforms/linux/initfiles/systemd/git-auto-deploy.service
index c73ff6c..1dd2ff0 100644
--- a/platforms/linux/initfiles/systemd/git-auto-deploy.service
+++ b/platforms/linux/initfiles/systemd/git-auto-deploy.service
@@ -5,7 +5,7 @@ Description=GitAutoDeploy
User=www-data
Group=www-data
WorkingDirectory=/opt/Git-Auto-Deploy/
-ExecStart=/usr/bin/python /opt/Git-Auto-Deploy/gitautodeploy --daemon-mode
+ExecStart=/usr/bin/python -m /opt/Git-Auto-Deploy/gitautodeploy --daemon-mode
[Install]
WantedBy=multi-user.target