Skip to content

Commit 9e07a52

Browse files
author
Gabriel Monroy
committed
Build.push classmethod for handling git-push through gitosis #35
1 parent 10d1429 commit 9e07a52

4 files changed

Lines changed: 64 additions & 43 deletions

File tree

api/models.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from celery.canvas import group
1616
from django.conf import settings
17+
from django.contrib.auth.models import User
1718
from django.db import models
1819
from django.db.models.signals import post_save
1920
from django.dispatch import receiver
@@ -682,6 +683,41 @@ class Meta:
682683
def __str__(self):
683684
return '{0}-v{1}'.format(self.formation.id, self.version)
684685

686+
@classmethod
687+
def push(cls, push):
688+
"""
689+
Process a push from a local Git server
690+
691+
Creates a new Build and returns the formation's
692+
databag for processing by the git-receive hook
693+
"""
694+
# SECURITY:
695+
# we assume the first part of the ssh key name
696+
# is the authenticated user because we trust gitosis
697+
username = push.pop('ssh_key').split('_')[0]
698+
# retrieve the user and formation instances
699+
user = User.objects.get(username=username)
700+
formation = Formation.objects.get(owner=push['owner'],
701+
id=push.pop('formation'))
702+
# merge the push with the required model instances
703+
push['owner'] = user
704+
push['formation'] = formation
705+
# create the build
706+
new_build = cls.objects.create(**push)
707+
# send a release signal
708+
release_signal.send(sender=push, build=new_build,
709+
formation=formation,
710+
user=user)
711+
# recalculate the formation databag including the new
712+
# build and release
713+
databag = formation.calculate()
714+
# if enabled, force-converge all of the chef nodes
715+
if settings.CONVERGE_ON_PUSH is True:
716+
formation.converge(databag)
717+
# return the databag object so the git-receive hook
718+
# can tell the user about proxy URLs, etc.
719+
return databag
720+
685721

686722
@python_2_unicode_compatible
687723
class Release(UuidAuditedModel):

bin/build-release-run

Lines changed: 0 additions & 40 deletions
This file was deleted.

bin/deis-push

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/opt/deis/controller/venv/bin/python
2+
import os
3+
import sys
4+
import json
5+
6+
if __name__ == '__main__':
7+
# prepare pythonpath and django settings
8+
base_path = os.path.abspath(os.path.join(__file__, '..', '..'))
9+
sys.path.insert(0, base_path)
10+
os.environ['DJANGO_SETTINGS_MODULE'] = 'deis.settings'
11+
from api import models
12+
# deserialize the json passed on stdin
13+
inp = sys.stdin.read()
14+
git_push = json.loads(inp)
15+
# process the push
16+
databag = models.Build.push(git_push)
17+
# print the databag json
18+
sys.stdout.write(json.dumps(databag))
19+
sys.stdout.flush()
20+
sys.exit(0)

deis/settings.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,13 @@
221221
}
222222
}
223223

224+
# import deis-specific settings files
225+
from .chef_settings import * # noqa @UnusedWildImport
226+
from .celery_settings import * # noqa @UnusedWildImport
227+
228+
# default deis settings
229+
CONVERGE_ON_PUSH = True
230+
224231
# Create a file named "local_settings.py" to contain sensitive settings data
225232
# such as database configuration, admin email, or passwords and keys. It
226233
# should also be used for any settings which differ between development
@@ -249,10 +256,8 @@
249256
# EMAIL_HOST_USER = 'foo'
250257
# EMAIL_HOST_PASSWORD = 'bar'
251258

252-
# import other settings
253-
from .chef_settings import * # noqa @UnusedWildImport
254-
from .celery_settings import * # noqa @UnusedWildImport
255259
try:
256260
from .local_settings import * # noqa @UnusedWildImport
257261
except ImportError:
258262
print('No deis/local_settings.py file found!')
263+

0 commit comments

Comments
 (0)