brew.py 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import os
  2. import logging
  3. import docker
  4. import git
  5. DEFAULT_REPOSITORY = 'git://github.com/dotcloud/docker'
  6. DEFAULT_BRANCH = 'library'
  7. logger = logging.getLogger(__name__)
  8. logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
  9. level='DEBUG')
  10. client = docker.Client()
  11. processed = {}
  12. def fetch_buildlist(repository=None, branch=None):
  13. if repository is None:
  14. repository = DEFAULT_REPOSITORY
  15. if branch is None:
  16. branch = DEFAULT_BRANCH
  17. logger.info('Cloning docker repo from {0}, branch: {1}'.format(
  18. repository, branch))
  19. #FIXME: set destination folder and only pull latest changes instead of
  20. # cloning the whole repo everytime
  21. dst_folder = git.clone_branch(repository, branch)
  22. for buildfile in os.listdir(os.path.join(dst_folder, 'library')):
  23. if buildfile == 'MAINTAINERS':
  24. continue
  25. f = open(os.path.join(dst_folder, 'library', buildfile))
  26. for line in f:
  27. logger.debug('{0} ---> {1}'.format(buildfile, line))
  28. args = line.split()
  29. try:
  30. if len(args) > 3:
  31. raise RuntimeError('Incorrect line format, '
  32. 'please refer to the docs')
  33. url = None
  34. ref = 'refs/heads/master'
  35. tag = None
  36. if len(args) == 1: # Just a URL, simple mode
  37. url = args[0]
  38. elif len(args) == 2 or len(args) == 3: # docker-tag url
  39. url = args[1]
  40. tag = args[0]
  41. if len(args) == 3: # docker-tag url B:branch or T:tag
  42. ref = None
  43. if args[2].startswith('B:'):
  44. ref = 'refs/heads/' + args[2][2:]
  45. elif args[2].startswith('T:'):
  46. ref = 'refs/tags/' + args[2][2:]
  47. elif args[2].startswith('C:'):
  48. ref = args[2][2:]
  49. else:
  50. raise RuntimeError('Incorrect line format, '
  51. 'please refer to the docs')
  52. img = start_build(url, ref, buildfile, tag)
  53. processed['{0}@{1}'.format(url, ref)] = img
  54. except Exception as e:
  55. logger.exception(e)
  56. f.close()
  57. def start_build(repository, ref, docker_repo, docker_tag=None, namespace=None,
  58. push=False):
  59. docker_repo = '{0}/{1}'.format(namespace or 'library', docker_repo)
  60. img_id = None
  61. if '{0}@{1}'.format(repository, ref) not in processed.keys():
  62. logger.info('Cloning {0} (ref: {1})'.format(repository, ref))
  63. dst_folder = git.clone(repository, ref)
  64. if not 'Dockerfile' in os.listdir(dst_folder):
  65. raise RuntimeError('Dockerfile not found in cloned repository')
  66. logger.info('Building using dockerfile...')
  67. img_id, logs = client.build_context(dst_folder)
  68. if not img_id:
  69. img_id = processed['{0}@{1}'.format(repository, ref)]
  70. logger.info('Committing to {0}:{1}'.format(docker_repo,
  71. docker_tag or 'latest'))
  72. client.tag(img_id, docker_repo, docker_tag)
  73. if push:
  74. logger.info('Pushing result to the main registry')
  75. client.push(docker_repo)
  76. return img_id