1. dready
  2. fabric_factory

Source

fabric_factory / src / factory / models.py

import tarfile
import bz2
import tempfile
import os
import logging
from cStringIO import StringIO



from django.db import models
from django.conf import settings
from factory.storage import FileSystemStorageUuidName
from factory import signals
from datetime import datetime

# Create your models here.
class FabfileRecipe(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField()
    notify = models.EmailField(blank=True)
    schedule = models.BooleanField() # or a charfield that lets you specify a job ID that matches the cronjob that will call schedule.py
    file = models.FileField(upload_to='factory/fabfiles')

    repos = models.CharField(max_length=255, blank=True,
                             help_text=u'URL of git repository to clone')
    projdir = models.CharField(max_length=255,
                               help_text=u'directory to cd into after clone, '
                                         u'including the name of the work tree')

    # default task
    #task = models.CharField(max_length=255)
    # proj repository (for "standard" fabfile)
    #url = models.URLField(verify_exists=False, max_length=200, blank=True)
    
    def __unicode__(self):
        return self.name


class Build(models.Model):
    name = models.CharField(max_length=255)
    task = models.CharField(max_length=255,
                            help_text='Space separated list of tasks')
    fabfile_recipe = models.ForeignKey(FabfileRecipe)

    # we can perhaps use this for the git revision to use?
    revision = models.CharField(max_length=255, null=True, blank=True)

    executed = models.BooleanField()
    executed_datetime = models.DateTimeField(blank=True, null=True)
    success = models.BooleanField()
    environement = models.TextField(null=True, blank=True)
    output = models.TextField(null=True, blank=True)
    error = models.TextField(null=True, blank=True)
    created_datetime = models.DateTimeField(auto_now_add=True, auto_now=True)

    #execution_time = models.IntegerField()
    #started_datetime = models.DateTimeField(blank=True, null=True)
    # from above (both reported by worker), we can find out the queued time

    def __unicode__(self):
        return self.name

    def save(self, force_insert=False, force_update=False, **kwargs):
        if self.executed:
            self.executed_datetime = datetime.now()
        return super(Build, self).save(force_insert, force_update, **kwargs)

    def make_build_package(self):
        """
        This method should build a compressed package containing the task runner,
        the fabfile. The task runner will be a python script that will execute
        the targeted tasks from the fabfile.
        """
        
        # Check if BUILD_PATH exist if it doesn't create it
        if not os.path.isdir(settings.BUILD_PATH):
            logging.debug("Create the directory : %s" %settings.BUILD_PATH)
            os.mkdir(settings.BUILD_PATH)
        # Make a tar of all the required files
        
        dst = tempfile.mktemp(prefix="%s_%s" %(self.id ,self.fabfile_recipe.slug),
                              suffix=".tar.bz2",
                              dir=settings.BUILD_PATH)
        logging.debug("Created temporary directory called : %s" %dst)
        try:
            out_tarfile = tarfile.TarFile.open(dst, mode="w:bz2")
            file = os.path.abspath(self.fabfile_recipe.file.path)
            
            out_tarfile.add( file, arcname='fabfile.py' )
            tarfile_name  = out_tarfile.name
            return os.path.basename(tarfile_name)
        finally:
            out_tarfile.close()


    def get_build_package_url(self):
        filename = self.make_build_package()
        return "%s/%s" %(settings.BUILD_URL, filename)



signals.connect(Build)