Skip to content

Commit

Permalink
No commit message
Browse files Browse the repository at this point in the history
  • Loading branch information
gmt2001 committed Jul 21, 2020
1 parent 305f680 commit 771f4bb
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
types: [published]

env:
OUROBOROS_VERSION: 1.5.1
OUROBOROS_VERSION: 1.6.0

jobs:
build:
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Change Log

## [v1.6.0](https://github.com/gmt2001/ouroboros/tree/v1.6.0) (2020-06-11)
[Full Changelog](https://github.com/gmt2001/ouroboros/compare/1.6.0...v1.5.1)

**Implemented enhancements:**

- Added hooks system

## [v1.5.1](https://github.com/gmt2001/ouroboros/tree/v1.5.1) (2020-06-11)
[Full Changelog](https://github.com/gmt2001/ouroboros/compare/1.5.1...v1.4.3)

Expand Down
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ COPY /pyouroboros /app/pyouroboros

RUN pip install --no-cache-dir .

RUN mkdir /app/pyouroboros/hooks

VOLUME /app/pyouroboros/hooks

ENTRYPOINT ["ouroboros"]
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ services:
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /app/pyouroboros/hooks:/app/pyouroboros/hooks
2 changes: 1 addition & 1 deletion pyouroboros/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
VERSION = "1.5.1"
VERSION = "1.6.0"
BRANCH = "master"
58 changes: 55 additions & 3 deletions pyouroboros/dockerclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from os.path import isdir, isfile, join
from docker.errors import DockerException, APIError, NotFound

from pyouroboros.helpers import set_properties, remove_sha_prefix, get_digest
from pyouroboros.helpers import set_properties, remove_sha_prefix, get_digest, run_hook


class Docker(object):
Expand Down Expand Up @@ -171,6 +171,7 @@ def recreate(self, container, latest_image):
self.logger.error('Unable to attach updated container to network "%s". Error: %s', network.name, e)

new_container.start()
return new_container

def pull(self, current_tag):
"""Docker pull image tag"""
Expand Down Expand Up @@ -299,24 +300,42 @@ def update(self):
updated_count = 0
try:
updateable, depends_on_containers, hard_depends_on_containers = self.socket_check()
locals = {}
locals['updateable'] = updateable
locals['depends_on_containers'] = depends_on_containers
locals['hard_depends_on_containers'] = hard_depends_on_containers
run_hook('updates_enumerated', None, locals)
except TypeError:
return

for container in depends_on_containers + hard_depends_on_containers:
locals = {}
locals['container'] = container
run_hook('before_stop_depends_container', None, locals)
self.stop(container)

for container, current_image, latest_image in updateable:
if self.config.dry_run:
# Ugly hack for repo digest
repo_digest_id = current_image.attrs['RepoDigests'][0].split('@')[1]
if repo_digest_id != latest_image.id:
locals = {}
locals['container'] = container
locals['current_image'] = current_image
locals['latest_image'] = latest_image
run_hook('dry_run_update', None, locals)
self.logger.info('dry run : %s would be updated', container.name)
continue

if self.config.monitor_only:
# Ugly hack for repo digest
repo_digest_id = current_image.attrs['RepoDigests'][0].split('@')[1]
if repo_digest_id != latest_image.id:
locals = {}
locals['container'] = container
locals['current_image'] = current_image
locals['latest_image'] = latest_image
run_hook('notify_update', None, locals)
self.notification_manager.send(
container_tuples=[(container.name, current_image, latest_image)],
socket=self.socket,
Expand All @@ -334,10 +353,22 @@ def update(self):

self.logger.info('%s will be updated', container.name)

self.recreate(container, latest_image)
locals = {}
locals['old_container'] = container
locals['old_image'] = current_image
locals['new_image'] = latest_image
run_hook('before_update', None, locals)

new_container = self.recreate(container, latest_image)

locals['new_container'] = new_container
run_hook('after_update', None, locals)

if self.config.cleanup:
try:
locals = {}
locals['image'] = current_image
run_hook('before_image_cleanup', None, locals)
self.client.images.remove(current_image.id)
except APIError as e:
self.logger.error("Could not delete old image for %s, Error: %s", container.name, e)
Expand All @@ -351,11 +382,19 @@ def update(self):

for container in depends_on_containers:
# Reload container to ensure it isn't referencing the old image
locals = {}
locals['container'] = container
run_hook('before_start_depends_container', None, locals)
container.reload()
container.start()

for container in hard_depends_on_containers:
self.recreate(container, container.image)
locals = {}
locals['old_container'] = container
run_hook('before_recreate_hard_depends_container', None, locals)
new_container = self.recreate(container, container.image)
locals['new_container'] = new_container
run_hook('after_recreate_hard_depends_container', None, locals)

if updated_count > 0:
self.notification_manager.send(container_tuples=updateable, socket=self.socket, kind='update')
Expand All @@ -367,24 +406,37 @@ def update_self(self, count=None, old_container=None, me_list=None, new_image=No
old_me = self.client.containers.get(old_me_id)
old_me_image_id = old_me.image.id

locals = {}
locals['old_container'] = old_me
locals['new_container'] = self.client.containers.get(me_list[0].id if me_list[0].attrs['Created'] >= me_list[1].attrs['Created'] else me_list[1].id)
run_hook('before_self_cleanup', None, locals)

old_me.stop()
old_me.remove()

self.client.images.remove(old_me_image_id)
self.logger.debug('Ahhh. All better.')
run_hook('after_self_cleanup', None, locals)

self.monitored = self.monitor_filter()
elif count == 1:
self.logger.debug('I need to update! Starting the ouroboros ;)')
self_name = 'ouroboros-updated' if old_container.name == 'ouroboros' else 'ouroboros'
new_config = set_properties(old=old_container, new=new_image, self_name=self_name)
locals = {}
locals['self_name'] = self_name
locals['old_container'] = old_container
locals['new_image'] = new_image
run_hook('before_self_update', None, locals)
try:
me_created = self.client.api.create_container(**new_config)
new_me = self.client.containers.get(me_created.get("Id"))
new_me.start()
self.logger.debug('If you strike me down, I shall become '
'more powerful than you could possibly imagine.')
self.logger.debug('https://bit.ly/2VVY7GH')
locals['new_container'] = new_me
run_hook('after_self_update', None, locals)
sleep(30)
except APIError as e:
self.logger.error("Self update failed.")
Expand Down
27 changes: 27 additions & 0 deletions pyouroboros/helpers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
from inspect import getframeinfo, currentframe
from os.path import dirname, abspath
from pathlib import Path

def get_exec_dir():
filename = getframeinfo(currentframe()).filename
path = dirname(abspath(filename))
if path.endswith('/'):
path = path[:-1]
return path

def run_hook(hookname, globals=None, locals=None):
pathlist = Path(get_exec_dir() + '/hooks/' + hookname).rglob('*.py')
for path in pathlist:
execfile(str(path), globals, locals)

# Copied from https://stackoverflow.com/a/41658338
def execfile(filepath, globals=None, locals=None):
if globals is None:
globals = {}
globals.update({
"__file__": filepath,
"__name__": "__main__",
})
with open(filepath, 'rb') as file:
exec(compile(file.read(), filepath, 'exec'), globals, locals)

def set_properties(old, new, self_name=None):
"""Store object for spawning new container in place of the one with outdated image"""
properties = {
Expand Down

1 comment on commit 771f4bb

@gmt2001
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add hooks system
Bump version number

Please sign in to comment.