瀏覽代碼

added build queue functionality

willpiper 4 年之前
父節點
當前提交
2c5d89ca66
共有 1 個文件被更改,包括 150 次插入125 次删除
  1. 150 125
      app.py

+ 150 - 125
app.py

@@ -9,7 +9,62 @@ import time
 import json
 
 from flask import Flask, render_template, request, flash
-from threading import Thread
+from threading import Thread, Lock
+
+queue_lock = Lock()
+
+def run_build(taskfile):
+    # run a build with parameters from task
+    task = json.loads(open(taskfile).read())
+    builddir = '/tmp/build'
+    subprocess.run(['./waf', 'configure', 
+                    '--board', task['board'], 
+                    '--out', builddir, 
+                    '--extra-hwdef', task['extra_hwdef']],
+                    cwd = task['sourcedir'])
+    subprocess.run(['./waf', 'clean'], cwd = task['sourcedir'])
+    subprocess.run(['./waf', task['vehicle']], cwd = task['sourcedir'])
+
+# background thread to check for queued build requests
+def check_queue():
+    while(1):
+        queue_lock.acquire()
+        listing = os.listdir(os.path.join(appdir, 'buildqueue'))
+        queue_lock.release()
+        if listing:
+            for token in listing:
+                print(token)
+                builddir = os.path.join('/private/tmp/build', token)
+                buildqueue_dir = os.path.join(appdir, 'buildqueue', token)
+                # check if build exists
+                if os.path.isdir(builddir):
+                    print("Build already exists")
+                else:
+                    # run build and rename build directory
+                    print(buildqueue_dir)
+                    run_build(os.path.join(buildqueue_dir, 'q.json'))
+                    f = open(os.path.join(buildqueue_dir, 'q.json'))
+                    task = json.load(f)
+                    os.rename(os.path.join('/private/tmp/build', task['board']), builddir)
+                
+                # remove working files
+                os.remove(os.path.join(buildqueue_dir, 'extra_hwdef.dat'))
+                os.remove(os.path.join(buildqueue_dir, 'q.json'))
+                os.rmdir(os.path.join(buildqueue_dir))
+
+                print("Build successful")
+        #time.sleep(1)
+
+# define source and app directories
+sourcedir = os.path.abspath('../ardupilot/')
+appdir = os.path.abspath(os.curdir)
+
+if not os.path.isdir('buildqueue'):
+    os.mkdir('buildqueue')
+
+thread = Thread(target=check_queue, args=())
+thread.daemon = True
+thread.start()
 
 # Directory of this file
 this_path = os.path.dirname(os.path.realpath(__file__))
@@ -23,143 +78,109 @@ tile_path = os.path.join(this_path, '..', 'data', 'tiles')
 # The output folder for all gzipped build requests
 app = Flask(__name__, static_url_path='/builds', static_folder=output_path,)
 
-def compressFiles(fileList, uuidkey):
+#def compressFiles(fileList, uuidkey):
     # create a zip file comprised of dat.gz tiles
-    zipthis = os.path.join(output_path, uuidkey + '.zip')
+    #zipthis = os.path.join(output_path, uuidkey + '.zip')
 
     # create output dirs if needed
-    try:
-        os.makedirs(output_path)
-    except OSError:
-        pass
-    try:
-        os.makedirs(tile_path)
-    except OSError:
-        pass
-
-    try:
-        with zipfile.ZipFile(zipthis, 'w') as terrain_zip:
-            for fn in fileList:
-                if not os.path.exists(fn):
-                    #download if required
-                    print("Downloading " + os.path.basename(fn))
-                    g = urllib.request.urlopen('https://terrain.ardupilot.org/data/tiles/' +
-                                               os.path.basename(fn))
-                    print("Downloaded " + os.path.basename(fn))
-                    with open(fn, 'b+w') as f:
-                        f.write(g.read())
+    #try:
+    #    os.makedirs(output_path)
+    #except OSError:
+    #    pass
+    #try:
+    #    os.makedirs(tile_path)
+    #except OSError:
+    #    pass
+
+    #try:
+    #    with zipfile.ZipFile(zipthis, 'w') as terrain_zip:
+    #        for fn in fileList:
+    #            if not os.path.exists(fn):
+    #                #download if required
+    #                print("Downloading " + os.path.basename(fn))
+    #                g = urllib.request.urlopen('https://terrain.ardupilot.org/data/tiles/' +
+    #                                           os.path.basename(fn))
+    #                print("Downloaded " + os.path.basename(fn))
+    #                with open(fn, 'b+w') as f:
+    #                    f.write(g.read())
 
                 # need to decompress file and pass to zip
-                with gzip.open(fn, 'r') as f_in:
-                    myio = BytesIO(f_in.read())
-                    print("Decomp " + os.path.basename(fn))
+    #            with gzip.open(fn, 'r') as f_in:
+    #                myio = BytesIO(f_in.read())
+    #                print("Decomp " + os.path.basename(fn))
 
                     # and add file to zip
-                    terrain_zip.writestr(os.path.basename(fn)[:-3], myio.read(),
-                                         compress_type=zipfile.ZIP_DEFLATED)
+    #                terrain_zip.writestr(os.path.basename(fn)[:-3], myio.read(),
+    #                                     compress_type=zipfile.ZIP_DEFLATED)
 
-    except Exception as ex:
-        print("Unexpected error: {0}".format(ex))
-        return False
+    #except Exception as ex:
+    #    print("Unexpected error: {0}".format(ex))
+    #    return False
 
-    return True
+    #return True
 
 @app.route('/')
 def index():
     return render_template('index.html')
 
-def run_build(taskfile):
-    # run a build with parameters from task
-    task = json.loads(open(taskfile).read())
-    builddir = '/tmp/build'
-    subprocess.run(['./waf', 'configure', 
-                    '--board', task['board'], 
-                    '--out', builddir, 
-                    '--extra-hwdef', task['extra_hwdef']],
-                    cwd = task['sourcedir'])
-    subprocess.run(['./waf', 'clean'], cwd = task['sourcedir'])
-    subprocess.run(['./waf', task['vehicle']], cwd = task['sourcedir'])
-
-def threaded_task():
-    for i in range(10):
-        print("Working... {}".format(i + 1))
-        time.sleep(1)
-
 @app.route('/generate', methods=['GET', 'POST'])
 def generate():
-    if request.method == 'POST':
-        features = []
-        task = {}
-
-        # fetch features from user input
-        for i in range(1,8):
-            value = request.form["option" + str(i)]
-            features.append(value)
-            undefine = "undef " + value.split()[1]
-            features.insert(0,undefine)
-        extra_hwdef = '\n'.join(features)
-
-        print("features: ", features)
-
-        thread = Thread(target=threaded_task, args=())
-        thread.daemon = True
-        thread.start()
-
-        # create extra_hwdef.dat file and obtain md5sum
-        file = open('buildqueue/extra_hwdef.dat',"w")
-        file.write(extra_hwdef)
-        file.close()
-        md5sum = subprocess.check_output(['md5sum', 'buildqueue/extra_hwdef.dat'],
-                                            encoding = 'utf-8')
-        md5sum = md5sum[:len(md5sum)-29]
-        os.remove('buildqueue/extra_hwdef.dat')
-
-        # define source and app directories
-        sourcedir = os.path.abspath('../ardupilot/')
-        appdir = os.path.abspath(os.curdir)
-
-        # obtain git-hash of source
-        git_hash = subprocess.check_output(['git', 'rev-parse', 'HEAD'], 
-                                            cwd = sourcedir,
-                                            encoding = 'utf-8')
-        git_hash = git_hash[:len(git_hash)-1]
-
-        # create directories using concatenated token of git-hash and md5sum of hwdef
-        token = git_hash + "-" + md5sum
-        buildqueue_dir = os.path.join(appdir, 'buildqueue', token)
-        if not os.path.isdir(buildqueue_dir):
-            os.mkdir(buildqueue_dir)
-        file = open(os.path.join(buildqueue_dir, 'extra_hwdef.dat'),"w")
-        file.write(extra_hwdef)
-        file.close()
-        
-        # fill dictionary of variables and create json file
-        task['hwdef_md5sum'] = md5sum
-        task['git_hash'] = git_hash
-        task['sourcedir'] = sourcedir
-        task['extra_hwdef'] = os.path.join(buildqueue_dir, 'extra_hwdef.dat')
-        task['board'] = request.form["board"]
-        task['vehicle'] = request.form["vehicle"]
-        jfile = open('{}/q.json'.format(buildqueue_dir), "w")
-        jfile.write(json.dumps(task))
-        jfile.close()
-
-        print(task)
-
-        # run build and rename build directory
-        builddir = os.path.join('/private/tmp/build', token)
-        if os.path.isdir(builddir):
-            print("Build already exists")
-        else:
-            run_build(os.path.join(buildqueue_dir, 'q.json'))
-            os.rename(os.path.join('/private/tmp/build', task['board']), builddir)
-
-        # remove working files
-        os.remove(os.path.join(buildqueue_dir, 'extra_hwdef.dat'))
-        os.remove(os.path.join(buildqueue_dir, 'q.json'))
-        os.rmdir(buildqueue_dir)
-
-        return render_template('generate.html')
+    #if request.method == 'POST':
+    features = []
+    task = {}
+
+    # fetch features from user input
+    for i in range(1,8):
+        value = request.form["option" + str(i)]
+        features.append(value)
+        undefine = "undef " + value.split()[1]
+        features.insert(0,undefine)
+    extra_hwdef = '\n'.join(features)
+
+    #print("features: ", features)
+
+    queue_lock.acquire()
+
+    # create extra_hwdef.dat file and obtain md5sum
+    file = open('buildqueue/extra_hwdef.dat',"w")
+    file.write(extra_hwdef)
+    file.close()
+    md5sum = subprocess.check_output(['md5sum', 'buildqueue/extra_hwdef.dat'],
+                                        encoding = 'utf-8')
+    md5sum = md5sum[:len(md5sum)-29]
+    os.remove('buildqueue/extra_hwdef.dat')
+
+    # obtain git-hash of source
+    git_hash = subprocess.check_output(['git', 'rev-parse', 'HEAD'], 
+                                        cwd = sourcedir,
+                                        encoding = 'utf-8')
+    git_hash = git_hash[:len(git_hash)-1]
+
+    # create directories using concatenated token of git-hash and md5sum of hwdef
+    token = git_hash + "-" + md5sum
+    buildqueue_dir = os.path.join(appdir, 'buildqueue', token)
+    if not os.path.isdir(buildqueue_dir):
+        os.mkdir(buildqueue_dir)
+    file = open(os.path.join(buildqueue_dir, 'extra_hwdef.dat'),"w")
+    file.write(extra_hwdef)
+    file.close()
+    
+    # fill dictionary of variables and create json file
+    task['hwdef_md5sum'] = md5sum
+    task['git_hash'] = git_hash
+    task['sourcedir'] = sourcedir
+    task['extra_hwdef'] = os.path.join(buildqueue_dir, 'extra_hwdef.dat')
+    task['board'] = request.form["board"]
+    task['vehicle'] = request.form["vehicle"]
+    jfile = open(os.path.join(buildqueue_dir, 'q.json'), "w")
+    jfile.write(json.dumps(task))
+    jfile.close()
+
+    queue_lock.release()
+
+    #print(task)
+
+    return render_template('building.html')
 
         # remove duplicates
         #filelist = list(dict.fromkeys(filelist))
@@ -182,9 +203,13 @@ def generate():
         #    print("Failed " + "/terrain/" + uuidkey + ".zip")
         #    return render_template('generate.html', error="Cannot generate terrain",
         #                           uuidkey=uuidkey)
-    else:
-        print("Bad get")
-        return render_template('generate.html', error="Need to use POST, not GET")
+    #else:
+    #    print("Bad get")
+    #    return render_template('generate.html', error="Need to use POST, not GET")
+
+@app.route('/home', methods=['POST'])
+def home():
+    return render_template('index.html')
 
 if __name__ == "__main__":
     app.run()