docker-build.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #!/usr/bin/env python3
  2. from os import environ, makedirs, chdir, listdir, rename
  3. from os.path import isdir
  4. from subprocess import call, check_call
  5. from shutil import *
  6. from multiprocessing import cpu_count
  7. from datetime import datetime
  8. from sys import stdout
  9. site = environ['GLUON_SITE']
  10. release = environ['GLUON_RELEASE']
  11. branch = environ['GLUON_BRANCH']
  12. broken = environ['GLUON_BROKEN']
  13. home = '/usr/src/build'
  14. gluondir = '%s/gluon' % home
  15. outdir = '%s/output/%s' % (home, release)
  16. logdir = '%s/log' % outdir
  17. siteconf = '/usr/src/site.conf'
  18. sitemk = '/usr/src/site.mk'
  19. i18ndir = '/usr/src/i18n'
  20. factorydir = '%s/images/factory' % outdir
  21. sysupdir = '%s/images/sysupgrade' % outdir
  22. modulesdir = '%s/modules' % outdir
  23. makedirs(factorydir)
  24. makedirs(sysupdir)
  25. makedirs(modulesdir)
  26. makedirs(logdir)
  27. start = datetime.now()
  28. def format_duration(d):
  29. s = d.total_seconds()
  30. return '%.2dh%.2dm%06.3fs' % (s//3600, (s//60)%60, s%60)
  31. # Clone Gluon
  32. if isdir(gluondir):
  33. rmtree(gluondir)
  34. print('Cloning Gluon... ', end=''); stdout.flush()
  35. with open('%s/git.log' % logdir, 'w') as log:
  36. check_call('git clone https://github.com/freifunk-gluon/gluon.git %s -b "%s"' % (gluondir, environ['GLUON_TAG']), stdout=log, stderr=log, shell=True)
  37. print('OK'); stdout.flush()
  38. # Add site configuration
  39. sitedir = '%s/site' % gluondir
  40. makedirs(sitedir)
  41. copy(siteconf, sitedir)
  42. copy(sitemk, sitedir)
  43. copytree(i18ndir, '%s/i18n' % sitedir)
  44. # Prepare
  45. chdir(gluondir)
  46. print('Updating other repositories... ', end=''); stdout.flush()
  47. with open('%s/update.log' % logdir, 'w') as log:
  48. check_call('make update V=s', stdout=log, stderr=log, shell=True)
  49. print('OK'); stdout.flush()
  50. # Choose targets to build
  51. if 'GLUON_TARGETS' in environ:
  52. targets = environ['GLUON_TARGETS'].split()
  53. else:
  54. targets = [f for f in listdir('targets') if isdir('targets/%s' % f)]
  55. # Build
  56. for target in targets:
  57. print('Building for target %s... ' % target, end=''); stdout.flush()
  58. arch, variant = target.split('-')
  59. target_start = datetime.now()
  60. with open('%s/%s_stdout.log' % (logdir, target), 'w') as logout, open('%s/%s_stderr.log' % (logdir, target), 'w') as logerr:
  61. rc = call('make -j %s GLUON_BRANCH=%s BROKEN=%s GLUON_TARGET=%s V=s' % (cpu_count()+1, branch, broken, target), stdout=logout, stderr=logerr, shell=True)
  62. duration = format_duration(datetime.now() - target_start)
  63. if rc == 0:
  64. print('OK in', duration)
  65. # Create manifest
  66. print('Creating manifest... ', end=''); stdout.flush()
  67. with open('%s/%s_manifest.log' % (logdir, target), 'w') as log:
  68. rc = call('make manifest GLUON_BRANCH=%s BROKEN=%s GLUON_TARGET=%s V=s' % (branch, broken, target), stdout=log, stderr=log, shell=True)
  69. if rc == 0:
  70. rename('output/images/sysupgrade/%s.manifest' % branch, 'output/images/sysupgrade/%s.%s.manifest' % (target, branch))
  71. print('OK')
  72. else:
  73. print('FAILED')
  74. stdout.flush()
  75. # Move images to output
  76. for f in listdir('output/images/factory'):
  77. rename('output/images/factory/%s' % f, '%s/%s' % (factorydir, f))
  78. for f in listdir('output/images/sysupgrade'):
  79. rename('output/images/sysupgrade/%s' % f, '%s/%s' % (sysupdir, f))
  80. # Move modules to output
  81. try:
  82. makedirs('%s/%s' % (modulesdir, arch))
  83. except FileExistsError:
  84. pass
  85. variantdir = '%s/%s/%s' % (modulesdir, arch, variant)
  86. rename('output/modules/gluon-%s-%s/%s/%s' % (site, release, arch, variant), variantdir)
  87. # Checksum modules
  88. print('Creating SHA512 sums for modules... ', end=''); stdout.flush()
  89. chdir(variantdir)
  90. check_call('sha512sum * > sha512sum.txt', shell=True)
  91. chdir(gluondir)
  92. print('OK')
  93. else:
  94. print('FAILED after', duration)
  95. # Clean up
  96. print('Cleaning up...', end=''); stdout.flush()
  97. with open('%s/%s_cleanup.log' % (logdir, target), 'w') as log:
  98. check_call('make dirclean V=s', stdout=log, stderr=log, shell=True)
  99. print('OK'); stdout.flush()
  100. print('Creating SHA512 sums for images... ', end=''); stdout.flush()
  101. for d in (factorydir, sysupdir):
  102. chdir(d)
  103. check_call('sha512sum * > sha512sum.txt', shell=True)
  104. print('OK')
  105. print('''
  106. BUILD FINISHED in %s
  107. You can copy the resulting images from the container using:
  108. docker cp %s:/usr/src/build/output <destination>
  109. '''% (format_duration(datetime.now() - start), environ['HOSTNAME']))