Source code for pyholodeck.maker

#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''Create .deb files from python venvs as artifacts for deployment

app_path is where we create the virtual env and it is also the
destination for the final target venv.  We cannot avoid this - .deb
creates it from dirs

todo: convert to run autmaotically within python (not pront cmds)
todo: discvover postinst files and add as cmd switches to fpm
todo: have some core service that postinst can call (fabric?)
todo: chain to build servers

We need to hace fpm natively installed

'''

import os
import pprint
import time

[docs]def gitfetch(url, parentfolder): '''Given a git url, retrieve to `parentfolder` '''
[docs]class SubCmd(object): '''Smoothly act as store of a subprocess cmd we want to have same command as a list for non-shell and in friendly form. nb Its a lot easier to .join a list than parse a string ''' def __init__(self, cmdlist, pythonstmt=None, args=None): self.cmdlist = cmdlist self.pythonstmt = pythonstmt self.args = args def __repr__(self): if self.pythonstmt: return str(self.pythonstmt) else: return " ".join(self.cmdlist)
import json
[docs]class DeployConfig(object): '''Accept json file, simple convervsion to hold it all lots of very big assumptions here ! ''' def __init__(self, filepath): jn = json.loads(open(filepath).read()) self.__dict__.update(jn) def __repr__(self): return "{} {}".format(self.__dict__['gitrepo'], self.__dict__['pkgname'])
[docs]class Deployment(object): '''A big wrapper around different stages in making the python package into a .deb We are building a simple solution 1. We build on local disk, in the expected locations, a venv representing the state of the venv we want eventually to deploy 2. We wrap that venv, with the python interpreter etc, into a `.deb` file (tarball basically). 3. We define a `saltstack` file that will deploy the .deb file artifact to our infrastructure. This file will define how to create the .ini / .conf files that will be put into well-known locations for the configuration of the package. 4. We define in the package the conf template for reference Alternatively the artifact can be a Docker image that contains our .deb file ''' #: the root where the final .deb installed code will get put #: it is also, for ease of building .debs, where we put the code #: so the .deb making stage can find it BASE_PATH = '/mikado' def __init__(self, app_name, giturl): self.app_name = app_name.lower() self.pkg_name = self.app_name self.app_path = os.path.join(self.BASE_PATH, self.app_name) self.venv_path = self.app_path #: where we will extract the git source to before runing setup self.src_path = os.path.join(self.app_path, self.pkg_name) + "-src" #: the interpreter in this venv self.python_exe = os.path.join(self.venv_path, 'bin/python') self.pip_exe = os.path.join(self.venv_path, 'bin/pip') self.giturl = giturl self.cmds = [] #for now just build bash commands for later def prepare_venv(self): #: build list of cmds to run. for cmd in ( SubCmd(['rm', '-rf', self.venv_path]), SubCmd(['mkdir', '-p', self.venv_path]), SubCmd(['mkdir', '-p', self.src_path]), SubCmd(['virtualenv', '-p', '/usr/bin/python', self.venv_path]), #replace with with #self.cmds.append('. {}/bin/activate'.format(self.venv_path)) SubCmd(['git', 'clone', self.giturl, self.src_path]), # SubCmd(['cd', self.src_path]), SubCmd([], os.chdir, [self.src_path]), #: dependancies SubCmd([self.pip_exe, 'install', '-r', 'requirements.txt']), SubCmd([self.python_exe, 'setup.py', 'install']), SubCmd(['fpm', '-s', 'dir', '-t', 'deb', '-p', '/tmp', '-n', self.pkg_name, self.venv_path]) ): self.cmds.append(cmd)
[docs]class Docker_Salt(object): ''' ''' pass
def demo(): d = Deployment('pyhello', 'github:mikadosoftware/pyhelloworld.git') d.prepare_venv() import subprocess for cmd in d.cmds: print cmd, "..." time.sleep(1.5) if not cmd.args: print subprocess.check_call(cmd.cmdlist) else: cmd.pythonstmt.__call__(*cmd.args) if __name__ == '__main__': import sys args = sys.argv[1:] if args: pkg = args[0] demo() else: print "really develop json contorl file" demo()