|
@@ -16,13 +16,14 @@ processed_folders = []
|
|
|
|
|
|
|
|
|
|
|
|
|
def build_library(repository=None, branch=None, namespace=None, push=False,
|
|
def build_library(repository=None, branch=None, namespace=None, push=False,
|
|
|
- debug=False, prefill=True, registry=None, targetlist=None, logger=None):
|
|
|
|
|
|
|
+ debug=False, prefill=True, registry=None, targetlist=None,
|
|
|
|
|
+ logger=None):
|
|
|
dst_folder = None
|
|
dst_folder = None
|
|
|
summary = Summary()
|
|
summary = Summary()
|
|
|
if logger is None:
|
|
if logger is None:
|
|
|
logger = logging.getLogger(__name__)
|
|
logger = logging.getLogger(__name__)
|
|
|
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
|
|
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
|
|
|
- level='INFO')
|
|
|
|
|
|
|
+ level='INFO')
|
|
|
|
|
|
|
|
if repository is None:
|
|
if repository is None:
|
|
|
repository = DEFAULT_REPOSITORY
|
|
repository = DEFAULT_REPOSITORY
|
|
@@ -32,8 +33,6 @@ def build_library(repository=None, branch=None, namespace=None, push=False,
|
|
|
logger.setLevel('DEBUG')
|
|
logger.setLevel('DEBUG')
|
|
|
if targetlist is not None:
|
|
if targetlist is not None:
|
|
|
targetlist = targetlist.split(',')
|
|
targetlist = targetlist.split(',')
|
|
|
- else:
|
|
|
|
|
- targetlist = []
|
|
|
|
|
|
|
|
|
|
if not (repository.startswith('https://') or repository.startswith('git://')):
|
|
if not (repository.startswith('https://') or repository.startswith('git://')):
|
|
|
logger.info('Repository provided assumed to be a local path')
|
|
logger.info('Repository provided assumed to be a local path')
|
|
@@ -43,9 +42,9 @@ def build_library(repository=None, branch=None, namespace=None, push=False,
|
|
|
client.version()
|
|
client.version()
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
logger.error('Could not reach the docker daemon. Please make sure it '
|
|
logger.error('Could not reach the docker daemon. Please make sure it '
|
|
|
- 'is running.')
|
|
|
|
|
|
|
+ 'is running.')
|
|
|
logger.warning('Also make sure you have access to the docker UNIX '
|
|
logger.warning('Also make sure you have access to the docker UNIX '
|
|
|
- 'socket (use sudo)')
|
|
|
|
|
|
|
+ 'socket (use sudo)')
|
|
|
return
|
|
return
|
|
|
|
|
|
|
|
#FIXME: set destination folder and only pull latest changes instead of
|
|
#FIXME: set destination folder and only pull latest changes instead of
|
|
@@ -58,16 +57,16 @@ def build_library(repository=None, branch=None, namespace=None, push=False,
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
logger.exception(e)
|
|
logger.exception(e)
|
|
|
logger.error('Source repository could not be fetched. Check '
|
|
logger.error('Source repository could not be fetched. Check '
|
|
|
- 'that the address is correct and the branch exists.')
|
|
|
|
|
|
|
+ 'that the address is correct and the branch exists.')
|
|
|
return
|
|
return
|
|
|
try:
|
|
try:
|
|
|
dirlist = os.listdir(os.path.join(dst_folder, 'library'))
|
|
dirlist = os.listdir(os.path.join(dst_folder, 'library'))
|
|
|
except OSError as e:
|
|
except OSError as e:
|
|
|
logger.error('The path provided ({0}) could not be found or didn\'t'
|
|
logger.error('The path provided ({0}) could not be found or didn\'t'
|
|
|
- 'contain a library/ folder.'.format(dst_folder))
|
|
|
|
|
|
|
+ 'contain a library/ folder.'.format(dst_folder))
|
|
|
return
|
|
return
|
|
|
for buildfile in dirlist:
|
|
for buildfile in dirlist:
|
|
|
- if buildfile == 'MAINTAINERS' or (len(targetlist) > 0 and buildfile not in targetlist):
|
|
|
|
|
|
|
+ if buildfile == 'MAINTAINERS' or (targetlist and buildfile not in targetlist):
|
|
|
continue
|
|
continue
|
|
|
f = open(os.path.join(dst_folder, 'library', buildfile))
|
|
f = open(os.path.join(dst_folder, 'library', buildfile))
|
|
|
linecnt = 0
|
|
linecnt = 0
|
|
@@ -78,7 +77,7 @@ def build_library(repository=None, branch=None, namespace=None, push=False,
|
|
|
try:
|
|
try:
|
|
|
if len(args) > 3:
|
|
if len(args) > 3:
|
|
|
raise RuntimeError('Incorrect line format, '
|
|
raise RuntimeError('Incorrect line format, '
|
|
|
- 'please refer to the docs')
|
|
|
|
|
|
|
+ 'please refer to the docs')
|
|
|
|
|
|
|
|
url = None
|
|
url = None
|
|
|
ref = 'refs/heads/master'
|
|
ref = 'refs/heads/master'
|
|
@@ -99,19 +98,19 @@ def build_library(repository=None, branch=None, namespace=None, push=False,
|
|
|
ref = args[2][2:]
|
|
ref = args[2][2:]
|
|
|
else:
|
|
else:
|
|
|
raise RuntimeError('Incorrect line format, '
|
|
raise RuntimeError('Incorrect line format, '
|
|
|
- 'please refer to the docs')
|
|
|
|
|
|
|
+ 'please refer to the docs')
|
|
|
if prefill:
|
|
if prefill:
|
|
|
logger.debug('Pulling {0} from official repository (cache '
|
|
logger.debug('Pulling {0} from official repository (cache '
|
|
|
- 'fill)'.format(buildfile))
|
|
|
|
|
|
|
+ 'fill)'.format(buildfile))
|
|
|
try:
|
|
try:
|
|
|
client.pull('stackbrew/' + buildfile)
|
|
client.pull('stackbrew/' + buildfile)
|
|
|
except:
|
|
except:
|
|
|
# Image is not on official repository, ignore prefill
|
|
# Image is not on official repository, ignore prefill
|
|
|
pass
|
|
pass
|
|
|
|
|
|
|
|
- img = build_repo(url, ref, buildfile, tag, namespace, push,
|
|
|
|
|
- registry, logger)
|
|
|
|
|
- summary.add_success(buildfile, (linecnt, line), img)
|
|
|
|
|
|
|
+ img, commit = build_repo(url, ref, buildfile, tag, namespace,
|
|
|
|
|
+ push, registry, logger)
|
|
|
|
|
+ summary.add_success(buildfile, (linecnt, line), img, commit)
|
|
|
processed['{0}@{1}'.format(url, ref)] = img
|
|
processed['{0}@{1}'.format(url, ref)] = img
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
logger.exception(e)
|
|
logger.exception(e)
|
|
@@ -127,34 +126,44 @@ def build_library(repository=None, branch=None, namespace=None, push=False,
|
|
|
|
|
|
|
|
|
|
|
|
|
def build_repo(repository, ref, docker_repo, docker_tag, namespace, push,
|
|
def build_repo(repository, ref, docker_repo, docker_tag, namespace, push,
|
|
|
- registry, logger):
|
|
|
|
|
|
|
+ registry, logger):
|
|
|
docker_repo = '{0}/{1}'.format(namespace or 'library', docker_repo)
|
|
docker_repo = '{0}/{1}'.format(namespace or 'library', docker_repo)
|
|
|
img_id = None
|
|
img_id = None
|
|
|
|
|
+ commit_id = None
|
|
|
dst_folder = None
|
|
dst_folder = None
|
|
|
if '{0}@{1}'.format(repository, ref) not in processed.keys():
|
|
if '{0}@{1}'.format(repository, ref) not in processed.keys():
|
|
|
|
|
+ rep = None
|
|
|
logger.info('Cloning {0} (ref: {1})'.format(repository, ref))
|
|
logger.info('Cloning {0} (ref: {1})'.format(repository, ref))
|
|
|
if repository not in processed:
|
|
if repository not in processed:
|
|
|
rep, dst_folder = git.clone(repository, ref)
|
|
rep, dst_folder = git.clone(repository, ref)
|
|
|
processed[repository] = rep
|
|
processed[repository] = rep
|
|
|
processed_folders.append(dst_folder)
|
|
processed_folders.append(dst_folder)
|
|
|
else:
|
|
else:
|
|
|
- dst_folder = git.checkout(processed[repository], ref)
|
|
|
|
|
|
|
+ rep = processed[repository]
|
|
|
|
|
+ dst_folder = git.checkout(rep, ref)
|
|
|
if not 'Dockerfile' in os.listdir(dst_folder):
|
|
if not 'Dockerfile' in os.listdir(dst_folder):
|
|
|
raise RuntimeError('Dockerfile not found in cloned repository')
|
|
raise RuntimeError('Dockerfile not found in cloned repository')
|
|
|
logger.info('Building using dockerfile...')
|
|
logger.info('Building using dockerfile...')
|
|
|
img_id, logs = client.build(path=dst_folder, quiet=True)
|
|
img_id, logs = client.build(path=dst_folder, quiet=True)
|
|
|
|
|
+ commit_id = rep.head()
|
|
|
else:
|
|
else:
|
|
|
|
|
+ logger.info('This ref has already been built, reusing image ID')
|
|
|
img_id = processed['{0}@{1}'.format(repository, ref)]
|
|
img_id = processed['{0}@{1}'.format(repository, ref)]
|
|
|
|
|
+ if ref.startswith('refs/'):
|
|
|
|
|
+ commit_id = processed[repository].ref(ref)
|
|
|
|
|
+ else:
|
|
|
|
|
+ commit_id = ref
|
|
|
logger.info('Committing to {0}:{1}'.format(docker_repo,
|
|
logger.info('Committing to {0}:{1}'.format(docker_repo,
|
|
|
- docker_tag or 'latest'))
|
|
|
|
|
|
|
+ docker_tag or 'latest'))
|
|
|
client.tag(img_id, docker_repo, docker_tag)
|
|
client.tag(img_id, docker_repo, docker_tag)
|
|
|
if push:
|
|
if push:
|
|
|
logger.info('Pushing result to registry {0}'.format(
|
|
logger.info('Pushing result to registry {0}'.format(
|
|
|
registry or "default"))
|
|
registry or "default"))
|
|
|
- push_repo(img_id, docker_repo, registry, logger)
|
|
|
|
|
- return img_id
|
|
|
|
|
|
|
+ push_repo(img_id, docker_repo, registry=registry, logger=logger)
|
|
|
|
|
+ return img_id, commit_id
|
|
|
|
|
+
|
|
|
|
|
|
|
|
-def push_repo(img_id, repo, registry=None, logger):
|
|
|
|
|
|
|
+def push_repo(img_id, repo, registry=None, docker_tag=None, logger=None):
|
|
|
exc = None
|
|
exc = None
|
|
|
if registry is not None:
|
|
if registry is not None:
|
|
|
repo = '{0}/{1}'.format(registry, repo)
|
|
repo = '{0}/{1}'.format(registry, repo)
|
|
@@ -162,11 +171,11 @@ def push_repo(img_id, repo, registry=None, logger):
|
|
|
client.tag(img_id, repo, docker_tag)
|
|
client.tag(img_id, repo, docker_tag)
|
|
|
for i in xrange(4):
|
|
for i in xrange(4):
|
|
|
try:
|
|
try:
|
|
|
- pushlog = client.push(docker_repo)
|
|
|
|
|
|
|
+ pushlog = client.push(repo)
|
|
|
if '"error":"' in pushlog:
|
|
if '"error":"' in pushlog:
|
|
|
raise RuntimeError('Error while pushing: {0}'.format(pushlog))
|
|
raise RuntimeError('Error while pushing: {0}'.format(pushlog))
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
exc = e
|
|
exc = e
|
|
|
continue
|
|
continue
|
|
|
return
|
|
return
|
|
|
- raise exc
|
|
|
|
|
|
|
+ raise exc
|