|
@@ -1,20 +1,12 @@
|
|
|
#!/usr/bin/env python3
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
-import uuid
|
|
|
|
|
import os
|
|
import os
|
|
|
-import sys
|
|
|
|
|
import subprocess
|
|
import subprocess
|
|
|
-import zipfile
|
|
|
|
|
-import urllib.request
|
|
|
|
|
-import gzip
|
|
|
|
|
-from io import BytesIO
|
|
|
|
|
-import time
|
|
|
|
|
import json
|
|
import json
|
|
|
import pathlib
|
|
import pathlib
|
|
|
import shutil
|
|
import shutil
|
|
|
|
|
+import glob
|
|
|
from distutils.dir_util import copy_tree
|
|
from distutils.dir_util import copy_tree
|
|
|
-import logging
|
|
|
|
|
-
|
|
|
|
|
from flask import Flask, render_template, request, flash
|
|
from flask import Flask, render_template, request, flash
|
|
|
from threading import Thread, Lock
|
|
from threading import Thread, Lock
|
|
|
|
|
|
|
@@ -38,17 +30,6 @@ dictConfig({
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
-'''
|
|
|
|
|
-Directory structure:
|
|
|
|
|
- - all paths relative to where the app starts
|
|
|
|
|
- - waf builds go into build
|
|
|
|
|
- - json queued build files go into buildqueue
|
|
|
|
|
- - resulting builds go into done
|
|
|
|
|
- - ardupilot is in ardupilot directory
|
|
|
|
|
- - templates in CustomBuild/templates
|
|
|
|
|
-
|
|
|
|
|
-'''
|
|
|
|
|
-
|
|
|
|
|
#def get_template(filename):
|
|
#def get_template(filename):
|
|
|
# return render_template(filename)
|
|
# return render_template(filename)
|
|
|
|
|
|
|
@@ -66,28 +47,32 @@ def remove_directory_recursive(dirname):
|
|
|
|
|
|
|
|
def create_directory(dir_path):
|
|
def create_directory(dir_path):
|
|
|
# create a directory, don't fail if it exists
|
|
# create a directory, don't fail if it exists
|
|
|
- app.logger.info('creating ' + dir_path)
|
|
|
|
|
|
|
+ app.logger.info('Creating ' + dir_path)
|
|
|
pathlib.Path(dir_path).mkdir(parents=True, exist_ok=True)
|
|
pathlib.Path(dir_path).mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
-def run_build(taskfile, builddir, done_dir):
|
|
|
|
|
|
|
+def run_build(taskfile, tmpdir, outdir):
|
|
|
# run a build with parameters from task
|
|
# run a build with parameters from task
|
|
|
- app.logger.info('Opening q.json')
|
|
|
|
|
|
|
+ app.logger.info('Opening ' + taskfile)
|
|
|
task = json.loads(open(taskfile).read())
|
|
task = json.loads(open(taskfile).read())
|
|
|
- remove_directory_recursive(os.path.join(sourcedir, done_dir))
|
|
|
|
|
- remove_directory_recursive(os.path.join(sourcedir, builddir))
|
|
|
|
|
- create_directory(os.path.join(sourcedir, done_dir))
|
|
|
|
|
- create_directory(os.path.join(sourcedir, builddir))
|
|
|
|
|
|
|
+ app.logger.info('Removing ' + taskfile)
|
|
|
|
|
+ os.remove(taskfile)
|
|
|
|
|
+ remove_directory_recursive(tmpdir)
|
|
|
|
|
+ create_directory(tmpdir)
|
|
|
|
|
+ if not os.path.isfile(os.path.join(outdir, 'extra_hwdef.dat')):
|
|
|
|
|
+ app.logger.error('Build aborted, missing extra_hwdef.dat')
|
|
|
app.logger.info('Creating build.log')
|
|
app.logger.info('Creating build.log')
|
|
|
- with open(os.path.join(sourcedir, done_dir, 'build.log'), "wb") as log:
|
|
|
|
|
|
|
+ #os.remove(os.path.join(outdir, 'build.log'))
|
|
|
|
|
+ with open(os.path.join(outdir, 'build.log'), 'a') as log:
|
|
|
app.logger.info('Submodule update')
|
|
app.logger.info('Submodule update')
|
|
|
subprocess.run(['git', 'submodule',
|
|
subprocess.run(['git', 'submodule',
|
|
|
'update', '--recursive',
|
|
'update', '--recursive',
|
|
|
- '--force', '--init'], stdout=log, stderr=log)
|
|
|
|
|
|
|
+ '--force', '--init'],
|
|
|
|
|
+ stdout=log, stderr=log)
|
|
|
app.logger.info('Running waf configure')
|
|
app.logger.info('Running waf configure')
|
|
|
subprocess.run(['./waf', 'configure',
|
|
subprocess.run(['./waf', 'configure',
|
|
|
'--board', task['board'],
|
|
'--board', task['board'],
|
|
|
- '--out', builddir,
|
|
|
|
|
|
|
+ '--out', tmpdir,
|
|
|
'--extra-hwdef', task['extra_hwdef']],
|
|
'--extra-hwdef', task['extra_hwdef']],
|
|
|
cwd = task['sourcedir'],
|
|
cwd = task['sourcedir'],
|
|
|
stdout=log, stderr=log)
|
|
stdout=log, stderr=log)
|
|
@@ -102,59 +87,53 @@ def run_build(taskfile, builddir, done_dir):
|
|
|
def check_queue():
|
|
def check_queue():
|
|
|
while(1):
|
|
while(1):
|
|
|
queue_lock.acquire()
|
|
queue_lock.acquire()
|
|
|
- listing = os.listdir('buildqueue')
|
|
|
|
|
|
|
+ json_files = list(filter(os.path.isfile,
|
|
|
|
|
+ glob.glob(os.path.join(outdir_parent,
|
|
|
|
|
+ '*', 'q.json'))))
|
|
|
|
|
+ json_files.sort(key=lambda x: os.path.getmtime(x))
|
|
|
queue_lock.release()
|
|
queue_lock.release()
|
|
|
- if listing:
|
|
|
|
|
- for token in listing:
|
|
|
|
|
- builddir = 'build'
|
|
|
|
|
- done_dir = os.path.join('done', token)
|
|
|
|
|
- buildqueue_dir = os.path.join('buildqueue', token)
|
|
|
|
|
|
|
+ if json_files:
|
|
|
|
|
+ for taskfile in json_files:
|
|
|
|
|
+ #taskfile = os.path.join(outdir, file)
|
|
|
|
|
+ app.logger.info('Opening ' + taskfile)
|
|
|
|
|
+ task = json.loads(open(taskfile).read())
|
|
|
|
|
+ outdir = os.path.join(outdir_parent, task['token'])
|
|
|
|
|
+ tmpdir = os.path.join(tmpdir_parent, task['token'])
|
|
|
# check if build exists
|
|
# check if build exists
|
|
|
- if os.path.isdir(os.path.join(sourcedir, done_dir)):
|
|
|
|
|
- app.logger.info('Build already exists')
|
|
|
|
|
- else:
|
|
|
|
|
- try:
|
|
|
|
|
- # run build and rename build directory
|
|
|
|
|
- app.logger.info('Creating ' +
|
|
|
|
|
- os.path.join(buildqueue_dir, 'q.json'))
|
|
|
|
|
- f = open(os.path.join(buildqueue_dir, 'q.json'))
|
|
|
|
|
- app.logger.info('Loading ' +
|
|
|
|
|
- os.path.join(buildqueue_dir, 'q.json'))
|
|
|
|
|
- task = json.load(f)
|
|
|
|
|
- run_build(os.path.join(buildqueue_dir, 'q.json'),
|
|
|
|
|
- builddir, done_dir)
|
|
|
|
|
- app.logger.info('Copying build files from %s to %s',
|
|
|
|
|
- os.path.join(sourcedir, builddir, task['board']),
|
|
|
|
|
- os.path.join(sourcedir, done_dir))
|
|
|
|
|
- copy_tree(os.path.join(sourcedir, builddir, task['board']),
|
|
|
|
|
- os.path.join(sourcedir, done_dir))
|
|
|
|
|
- app.logger.info('Build successful!')
|
|
|
|
|
-
|
|
|
|
|
- except:
|
|
|
|
|
- app.logger.info('Build failed')
|
|
|
|
|
- continue
|
|
|
|
|
|
|
+ #if os.path.isdir(outdir):
|
|
|
|
|
+ #app.logger.info('Build already exists')
|
|
|
|
|
+ #app.logger.info('Removing ' + taskfile)
|
|
|
|
|
+ #os.remove(taskfile)
|
|
|
|
|
+ #else:
|
|
|
|
|
+ try:
|
|
|
|
|
+ # run build and rename build directory
|
|
|
|
|
+ app.logger.info('Opening ' + taskfile)
|
|
|
|
|
+ f = open(taskfile)
|
|
|
|
|
+ app.logger.info('Loading ' + taskfile)
|
|
|
|
|
+ task = json.load(f)
|
|
|
|
|
+ run_build(taskfile, tmpdir, outdir)
|
|
|
|
|
+ app.logger.info('Copying build files from %s to %s',
|
|
|
|
|
+ os.path.join(tmpdir, task['board']),
|
|
|
|
|
+ outdir)
|
|
|
|
|
+ copy_tree(os.path.join(tmpdir, task['board'], 'bin'),
|
|
|
|
|
+ outdir)
|
|
|
|
|
+ app.logger.info('Build successful!')
|
|
|
|
|
+ app.logger.info('Removing ' + tmpdir)
|
|
|
|
|
+ remove_directory_recursive(tmpdir)
|
|
|
|
|
+ # remove extra_hwdef.dat
|
|
|
|
|
+ app.logger.info('Removing ' +
|
|
|
|
|
+ os.path.join(outdir, 'extra_hwdef.dat'))
|
|
|
|
|
+ os.remove(os.path.join(outdir, 'extra_hwdef.dat'))
|
|
|
|
|
|
|
|
- # remove working files
|
|
|
|
|
- app.logger.info('Removing ' +
|
|
|
|
|
- os.path.join(buildqueue_dir, 'extra_hwdef.dat'))
|
|
|
|
|
- os.remove(os.path.join(buildqueue_dir, 'extra_hwdef.dat'))
|
|
|
|
|
- app.logger.info('Removing ' +
|
|
|
|
|
- os.path.join(buildqueue_dir, 'q.json'))
|
|
|
|
|
- os.remove(os.path.join(buildqueue_dir, 'q.json'))
|
|
|
|
|
- app.logger.info('Removing ' +
|
|
|
|
|
- os.path.join(buildqueue_dir))
|
|
|
|
|
- os.rmdir(os.path.join(buildqueue_dir))
|
|
|
|
|
-
|
|
|
|
|
-# define source and app directories
|
|
|
|
|
-sourcedir = os.path.abspath(os.path.join('..', 'ardupilot'))
|
|
|
|
|
-appdir = os.path.abspath(os.curdir)
|
|
|
|
|
|
|
+ except:
|
|
|
|
|
+ app.logger.info('Build failed')
|
|
|
|
|
+ continue
|
|
|
|
|
|
|
|
-if not os.path.isdir('buildqueue'):
|
|
|
|
|
- os.mkdir('buildqueue')
|
|
|
|
|
-
|
|
|
|
|
-thread = Thread(target=check_queue, args=())
|
|
|
|
|
-thread.daemon = True
|
|
|
|
|
-thread.start()
|
|
|
|
|
|
|
+# define directories
|
|
|
|
|
+basedir = os.path.abspath('..')
|
|
|
|
|
+sourcedir = os.path.abspath(os.path.join(basedir, 'ardupilot'))
|
|
|
|
|
+outdir_parent = os.path.join(basedir, 'builds')
|
|
|
|
|
+tmpdir_parent = os.path.join(basedir, 'tmp')
|
|
|
|
|
|
|
|
# Directory of this file
|
|
# Directory of this file
|
|
|
this_path = os.path.dirname(os.path.realpath(__file__))
|
|
this_path = os.path.dirname(os.path.realpath(__file__))
|
|
@@ -169,6 +148,13 @@ tile_path = os.path.join(this_path, '..', 'data', 'tiles')
|
|
|
app = Flask(__name__, static_url_path='/builds',
|
|
app = Flask(__name__, static_url_path='/builds',
|
|
|
static_folder=output_path, template_folder='templates')
|
|
static_folder=output_path, template_folder='templates')
|
|
|
|
|
|
|
|
|
|
+if not os.path.isdir(outdir_parent):
|
|
|
|
|
+ create_directory(outdir_parent)
|
|
|
|
|
+
|
|
|
|
|
+thread = Thread(target=check_queue, args=())
|
|
|
|
|
+thread.daemon = True
|
|
|
|
|
+thread.start()
|
|
|
|
|
+
|
|
|
@app.route('/')
|
|
@app.route('/')
|
|
|
def index():
|
|
def index():
|
|
|
app.logger.info('Rendering index.html')
|
|
app.logger.info('Rendering index.html')
|
|
@@ -184,29 +170,32 @@ def generate():
|
|
|
# fetch features from user input
|
|
# fetch features from user input
|
|
|
app.logger.info('Fetching features from user input')
|
|
app.logger.info('Fetching features from user input')
|
|
|
for i in range(1,8):
|
|
for i in range(1,8):
|
|
|
- value = request.form["option" + str(i)]
|
|
|
|
|
|
|
+ value = request.form['option' + str(i)]
|
|
|
features.append(value)
|
|
features.append(value)
|
|
|
- undefine = "undef " + value.split()[1]
|
|
|
|
|
|
|
+ undefine = 'undef ' + value.split()[1]
|
|
|
features.insert(0,undefine)
|
|
features.insert(0,undefine)
|
|
|
extra_hwdef = '\n'.join(features)
|
|
extra_hwdef = '\n'.join(features)
|
|
|
|
|
|
|
|
- #print("features: ", features)
|
|
|
|
|
-
|
|
|
|
|
queue_lock.acquire()
|
|
queue_lock.acquire()
|
|
|
|
|
|
|
|
# create extra_hwdef.dat file and obtain md5sum
|
|
# create extra_hwdef.dat file and obtain md5sum
|
|
|
- app.logger.info('Creating ' + os.path.join('buildqueue', 'extra_hwdef.dat'))
|
|
|
|
|
- file = open(os.path.join('buildqueue', 'extra_hwdef.dat'),"w")
|
|
|
|
|
|
|
+ app.logger.info('Creating ' +
|
|
|
|
|
+ os.path.join(outdir_parent, 'extra_hwdef.dat'))
|
|
|
|
|
+ file = open(os.path.join(outdir_parent, 'extra_hwdef.dat'),'w')
|
|
|
app.logger.info('Writing\n' + extra_hwdef)
|
|
app.logger.info('Writing\n' + extra_hwdef)
|
|
|
file.write(extra_hwdef)
|
|
file.write(extra_hwdef)
|
|
|
file.close()
|
|
file.close()
|
|
|
app.logger.info('Getting md5sum')
|
|
app.logger.info('Getting md5sum')
|
|
|
- md5sum = subprocess.check_output(['md5sum', 'buildqueue/extra_hwdef.dat'],
|
|
|
|
|
|
|
+ md5sum = subprocess.check_output(['md5sum',
|
|
|
|
|
+ os.path.join(outdir_parent,
|
|
|
|
|
+ 'extra_hwdef.dat')],
|
|
|
encoding = 'utf-8')
|
|
encoding = 'utf-8')
|
|
|
- md5sum = md5sum[:len(md5sum)-29]
|
|
|
|
|
|
|
+ md5sum = md5sum[:len(md5sum)
|
|
|
|
|
+ -(3+len(os.path.join(outdir_parent, 'extra_hwdef.dat')))]
|
|
|
app.logger.info('md5sum = ' + md5sum)
|
|
app.logger.info('md5sum = ' + md5sum)
|
|
|
- app.logger.info('Removing ' + os.path.join('buildqueue', 'extra_hwdef.dat'))
|
|
|
|
|
- os.remove(os.path.join('buildqueue', 'extra_hwdef.dat'))
|
|
|
|
|
|
|
+ app.logger.info('Removing ' +
|
|
|
|
|
+ os.path.join(outdir_parent, 'extra_hwdef.dat'))
|
|
|
|
|
+ os.remove(os.path.join(outdir_parent, 'extra_hwdef.dat'))
|
|
|
|
|
|
|
|
# obtain git-hash of source
|
|
# obtain git-hash of source
|
|
|
app.logger.info('Getting git hash')
|
|
app.logger.info('Getting git hash')
|
|
@@ -216,43 +205,57 @@ def generate():
|
|
|
git_hash = git_hash[:len(git_hash)-1]
|
|
git_hash = git_hash[:len(git_hash)-1]
|
|
|
app.logger.info('Git hash = ' + git_hash)
|
|
app.logger.info('Git hash = ' + git_hash)
|
|
|
|
|
|
|
|
- # create directories using concatenated token of git-hash and md5sum of hwdef
|
|
|
|
|
- token = git_hash + "-" + md5sum
|
|
|
|
|
|
|
+ # create directories using concatenated token
|
|
|
|
|
+ # of vehicle, board, git-hash of source, and md5sum of hwdef
|
|
|
|
|
+ vehicle = request.form['vehicle']
|
|
|
|
|
+ board = request.form['board']
|
|
|
|
|
+ token = vehicle + '-' + board + '-' + git_hash + '-' + md5sum
|
|
|
app.logger.info('token = ' + token)
|
|
app.logger.info('token = ' + token)
|
|
|
- buildqueue_dir = os.path.join(appdir, 'buildqueue', token)
|
|
|
|
|
- if not os.path.isdir(buildqueue_dir):
|
|
|
|
|
- app.logger.info('Creating ' + buildqueue_dir)
|
|
|
|
|
- os.mkdir(buildqueue_dir)
|
|
|
|
|
- app.logger.info('Opening ' + os.path.join(buildqueue_dir, 'extra_hwdef.dat'))
|
|
|
|
|
- file = open(os.path.join(buildqueue_dir, 'extra_hwdef.dat'),"w")
|
|
|
|
|
- app.logger.info('Writing\n' + extra_hwdef)
|
|
|
|
|
- file.write(extra_hwdef)
|
|
|
|
|
- file.close()
|
|
|
|
|
|
|
+ outdir = os.path.join(outdir_parent, token)
|
|
|
|
|
|
|
|
- # fill dictionary of variables and create json file
|
|
|
|
|
- task['hwdef_md5sum'] = md5sum
|
|
|
|
|
- task['git_hash'] = git_hash
|
|
|
|
|
- task['token'] = token
|
|
|
|
|
- task['sourcedir'] = sourcedir
|
|
|
|
|
- task['extra_hwdef'] = os.path.join(buildqueue_dir, 'extra_hwdef.dat')
|
|
|
|
|
- task['board'] = request.form["board"]
|
|
|
|
|
- task['vehicle'] = request.form["vehicle"]
|
|
|
|
|
- app.logger.info('Opening ' + os.path.join(buildqueue_dir, 'q.json'))
|
|
|
|
|
- jfile = open(os.path.join(buildqueue_dir, 'q.json'), "w")
|
|
|
|
|
- app.logger.info('Writing task file to ' + os.path.join(buildqueue_dir, 'q.json'))
|
|
|
|
|
- jfile.write(json.dumps(task))
|
|
|
|
|
- jfile.close()
|
|
|
|
|
|
|
+ if os.path.isdir(outdir):
|
|
|
|
|
+ app.logger.info('Build already exists')
|
|
|
|
|
+ else:
|
|
|
|
|
+ app.logger.info('Creating ' + outdir)
|
|
|
|
|
+ create_directory(outdir)
|
|
|
|
|
+ # create build.log
|
|
|
|
|
+ app.logger.info('Creating build.log')
|
|
|
|
|
+ build_log = open(os.path.join(outdir, 'build.log'), 'w')
|
|
|
|
|
+ build_log.write('Waiting for build to start...\n')
|
|
|
|
|
+ build_log.close()
|
|
|
|
|
+ # create hwdef.dat
|
|
|
|
|
+ app.logger.info('Opening ' + os.path.join(outdir, 'extra_hwdef.dat'))
|
|
|
|
|
+ file = open(os.path.join(outdir, 'extra_hwdef.dat'),'w')
|
|
|
|
|
+ app.logger.info('Writing\n' + extra_hwdef)
|
|
|
|
|
+ file.write(extra_hwdef)
|
|
|
|
|
+ file.close()
|
|
|
|
|
+ # fill dictionary of variables and create json file
|
|
|
|
|
+ task['hwdef_md5sum'] = md5sum
|
|
|
|
|
+ task['git_hash'] = git_hash
|
|
|
|
|
+ task['token'] = token
|
|
|
|
|
+ task['sourcedir'] = sourcedir
|
|
|
|
|
+ task['extra_hwdef'] = os.path.join(outdir, 'extra_hwdef.dat')
|
|
|
|
|
+ task['board'] = board
|
|
|
|
|
+ task['vehicle'] = vehicle
|
|
|
|
|
+ app.logger.info('Opening ' + os.path.join(outdir, 'q.json'))
|
|
|
|
|
+ jfile = open(os.path.join(outdir, 'q.json'), 'w')
|
|
|
|
|
+ app.logger.info('Writing task file to ' + os.path.join(outdir, 'q.json'))
|
|
|
|
|
+ jfile.write(json.dumps(task))
|
|
|
|
|
+ jfile.close()
|
|
|
|
|
|
|
|
queue_lock.release()
|
|
queue_lock.release()
|
|
|
|
|
|
|
|
- #print(task)
|
|
|
|
|
-
|
|
|
|
|
- apache_build_dir = "http://localhost:8080/" + token
|
|
|
|
|
- apache_build_log = "http://localhost:8080/" + token + "/build.log"
|
|
|
|
|
|
|
+ apache_build_dir = 'http://localhost:8080/' \
|
|
|
|
|
+ + os.path.join('builds', token)
|
|
|
|
|
+ apache_build_log = 'http://localhost:8080/' \
|
|
|
|
|
+ + os.path.join('builds', token, 'build.log')
|
|
|
|
|
+ apache_all_builds = 'http://localhost:8080/' \
|
|
|
|
|
+ + 'builds'
|
|
|
app.logger.info('Rendering generate.html')
|
|
app.logger.info('Rendering generate.html')
|
|
|
return render_template('generate.html',
|
|
return render_template('generate.html',
|
|
|
apache_build_dir=apache_build_dir,
|
|
apache_build_dir=apache_build_dir,
|
|
|
apache_build_log=apache_build_log,
|
|
apache_build_log=apache_build_log,
|
|
|
|
|
+ apache_all_builds=apache_all_builds,
|
|
|
token=token)
|
|
token=token)
|
|
|
|
|
|
|
|
except:
|
|
except:
|
|
@@ -263,5 +266,5 @@ def home():
|
|
|
app.logger.info('Rendering index.html')
|
|
app.logger.info('Rendering index.html')
|
|
|
return render_template('index.html')
|
|
return render_template('index.html')
|
|
|
|
|
|
|
|
-if __name__ == "__main__":
|
|
|
|
|
|
|
+if __name__ == '__main__':
|
|
|
app.run()
|
|
app.run()
|