blob: 7d4c7e598ee4edb364d92ad039df10931beba48c [file] [log] [blame]
import os
import base64
import string
import sys
import urllib2
import urlparse
import xmlrpclib
from xos.config import Config
from core.models import Service, ServiceController, ServiceControllerResource
from xos.logger import Logger, logging
logger = Logger(level=logging.INFO)
class XOSBuilder(object):
UI_KINDS=["models", "admin", "django_library", "rest", "tosca_custom_types", "tosca_resource"]
SYNC_KINDS=["synchronizer"]
def __init__(self):
self.source_ui_image = "xosproject/xos"
self.source_sync_image = "xosproject/xos-synchronizer-openstack"
self.build_dir = "/opt/xos/BUILD/"
# stuff that has to do with downloading
def get_dest_dir(self, scr):
xos_base = "opt/xos"
service_name = scr.service_controller.name
base_dirs = {"models": "%s/services/%s/" % (xos_base, service_name),
"admin": "%s/services/%s/" % (xos_base, service_name),
"django_library": "%s/services/%s/" % (xos_base, service_name),
"synchronizer": "%s/synchronizers/%s/" % (xos_base, service_name),
"tosca_custom_types": "%s/tosca/custom_types/" % (xos_base),
"tosca_resource": "%s/tosca/resources/" % (xos_base)}
return base_dirs[scr.kind]
def get_build_fn(self, scr):
dest_dir = self.get_dest_dir(scr)
dest_fn = os.path.split(urlparse.urlsplit(scr.full_url).path)[-1]
return os.path.join(dest_dir, dest_fn)
def get_download_fn(self, scr):
dest_fn = self.get_build_fn(scr)
return os.path.join(self.build_dir, dest_fn)
def read_manifest(self, scr, fn):
manifest = []
manifest_lines = file(fn).readlines()
manifest_lines = [x.strip() for x in manifest_lines]
manifest_lines = [x for x in manifest.lines if x]
for line in manifest_lines:
url_parts = urlsplit(scr.full_url)
url_parts.path = os.path.join(os.path.join(*os.path.split(url_parts).path[:-1]),line)
url = urlparse.urlunsplit(url_parts)
build_fn = os.path.join(self.get_dest_dir(scr), line)
manifest.append( (url, download_fn, build_fn) )
return manifest
def download_file(self, url, dest_fn):
logger.info("Download %s to %s" % (url, dest_fn))
if not os.path.exists(os.path.dirname(dest_fn)):
os.makedirs(os.path.dirname(dest_fn))
obj = urllib2.urlopen(url)
file(dest_fn,"w").write(obj.read())
def download_resource(self, scr):
if scr.format == "manifest":
manifest_fn = self.get_download_fn(scr)
self.download_file(scr.full_url, manifest_fn)
mainfest = self.read_manifest(scr, manifest_fn)
for (url, download_fn, build_fn) in manifest:
self.download_file(url, download_fn)
else:
self.download_file(scr.full_url, self.get_download_fn(scr))
def get_docker_lines(self, scr):
if scr.format == "manifest":
manifest_fn = self.get_download_fn(scr)
manifest = self.read_manifest(scr, manifest_fn)
lines = []
for (url, download_fn, build_fn) in manifest:
lines.append("ADD %s /%s" % (build_fn, build_fn))
return lines
else:
build_fn = self.get_build_fn(scr)
return ["ADD %s /%s" % (build_fn, build_fn)]
def get_controller_docker_lines(self, controller, kinds):
dockerfile=[]
for scr in controller.service_controller_resources.all():
if scr.kind in kinds:
lines = self.get_docker_lines(scr)
dockerfile = dockerfile + lines
return dockerfile
# stuff that has to do with building
def create_ui_dockerfile(self):
dockerfile_fn = "Dockerfile.UI"
dockerfile = ["FROM %s" % self.source_ui_image]
for controller in ServiceController.objects.all():
dockerfile = dockerfile + self.get_controller_docker_lines(controller, self.UI_KINDS)
file(os.path.join(self.build_dir, dockerfile_fn), "w").write("\n".join(dockerfile)+"\n")
return [dockerfile_fn]
def create_synchronizer_dockerfile(self, controller):
lines = self.get_controller_docker_lines(controller, self.SYNC_KINDS)
if not lines:
return []
dockerfile_fn = "Dockerfile.%s" % controller.name
dockerfile = ["FROM %s" % self.source_sync_image]
dockerfile = dockerfile + lines
file(os.path.join(self.build_dir, dockerfile_fn), "w").writelines(dockerfile)
return [dockerfile_fn]
def run_docker(self, dockerfile_fn):
pass
def build_xos(self):
dockerfiles=[]
dockerfiles = dockerfiles + self.create_ui_dockerfile()
for controller in ServiceController.objects.all():
dockerfiles = dockerfiles + self.create_synchronizer_dockerfile(controller)
for dockerfile in dockerfiles:
self.run_docker(dockerfile)