Merge "Support docker for ota generator"

This commit is contained in:
Kelvin Zhang
2021-07-29 12:54:42 +00:00
committed by Gerrit Code Review
11 changed files with 68 additions and 13 deletions

View File

@@ -0,0 +1,2 @@
node_modules/
Dockerfile

View File

@@ -0,0 +1 @@
NODE_ENV=development

View File

@@ -0,0 +1 @@
NODE_ENV=production

View File

@@ -5,6 +5,8 @@ node_modules
/output /output
stderr* stderr*
stdout* stdout*
yarn.lock
otatools.zip
# local env files # local env files

20
tools/otagui/Dockerfile Normal file
View File

@@ -0,0 +1,20 @@
# build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# production stage
FROM ubuntu:20.04 as production-stage
RUN apt-get update && apt-get --no-install-recommends install -y python3.9 unzip xxd cgpt unzip openjdk-16-jre-headless zip less
WORKDIR /app
VOLUME [ "/app/target", "/app/output"]
COPY otatools.zip .
COPY --from=build-stage /app/dist ./dist
COPY --from=build-stage /app/*.py .
EXPOSE 8000
CMD ["python3.9", "web_server.py"]

View File

@@ -27,3 +27,8 @@ Finally, run the python http-server and vue.js server:
python3 web_server.py & python3 web_server.py &
npm run serve npm run serve
``` ```
### Run with Docker
1. Build the image `docker build -t zhangxp1998/test .`
2. Run: `docker run -it -p 8000:8000 -v target:/app/target -v output:/app/output zhangxp1998/test:latest`

View File

@@ -89,7 +89,7 @@ class ProcessesManagement:
A class manage the ota generate process A class manage the ota generate process
""" """
def __init__(self, path='ota_database.db'): def __init__(self, path='output/ota_database.db'):
""" """
create a table if not exist create a table if not exist
""" """
@@ -156,9 +156,9 @@ class ProcessesManagement:
'output', 'stdout.'+str(id)), 'w') 'output', 'stdout.'+str(id)), 'w')
try: try:
proc = subprocess.Popen( proc = subprocess.Popen(
command, stderr=ferr, stdout=fout) command, stderr=ferr, stdout=fout, shell=False)
except FileNotFoundError: except FileNotFoundError as e:
logging.error('ota_from_target_files is not set properly') logging.error('ota_from_target_files is not set properly %s', e)
self.update_status(id, 'Error', int(time.time())) self.update_status(id, 'Error', int(time.time()))
return return
exit_code = proc.wait() exit_code = proc.wait()
@@ -182,7 +182,7 @@ class ProcessesManagement:
command += args['extra'].split(' ') command += args['extra'].split(' ')
command.append('-k') command.append('-k')
command.append( command.append(
'../../../build/make/target/product/security/testkey') 'build/make/target/product/security/testkey')
if args['isIncremental']: if args['isIncremental']:
if not os.path.isfile(args['incremental']): if not os.path.isfile(args['incremental']):
raise FileNotFoundError raise FileNotFoundError

View File

@@ -1,15 +1,22 @@
import axios from 'axios' import axios from 'axios'
const baseURL = process.env.NODE_ENV === 'production' ? '' : 'http://localhost:8000';
console.log(`Build mode: ${process.env.NODE_ENV}, API base url ${baseURL}`);
const apiClient = axios.create({ const apiClient = axios.create({
baseURL: 'http://localhost:8000', baseURL,
withCredentials: false, withCredentials: false,
headers: { headers: {
Accept: 'application/json', Accept: 'application/json',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
} }
}) });
export default { export default {
getDownloadURLForJob(job) {
return `${baseURL}/download/${job.output}`;
},
getJobs() { getJobs() {
return apiClient.get("/check") return apiClient.get("/check")
}, },

View File

@@ -63,7 +63,7 @@ export default {
}, },
computed: { computed: {
download() { download() {
return 'http://localhost:8000/download/' + this.job.output return ApiService.getDownloadURLForJob(this.job);
}, },
}, },
created() { created() {

View File

@@ -71,7 +71,7 @@ class TargetLib:
""" """
A class that manages the builds in database. A class that manages the builds in database.
""" """
def __init__(self, path='ota_database.db'): def __init__(self, path='target/ota_database.db'):
""" """
Create a build table if not existing Create a build table if not existing
""" """

View File

@@ -30,11 +30,11 @@ from ota_interface import ProcessesManagement
from target_lib import TargetLib from target_lib import TargetLib
import logging import logging
import json import json
import pipes
import cgi import cgi
import subprocess
import os import os
import stat
import sys import sys
import zipfile
LOCAL_ADDRESS = '0.0.0.0' LOCAL_ADDRESS = '0.0.0.0'
@@ -142,7 +142,10 @@ class RequestHandler(CORSSimpleHTTPHandler):
file_length -= len(self.rfile.readline()) file_length -= len(self.rfile.readline())
file_length -= len(self.rfile.readline()) file_length -= len(self.rfile.readline())
file_length -= len(self.rfile.readline()) file_length -= len(self.rfile.readline())
output_file.write(self.rfile.read(file_length)) BUFFER_SIZE = 1024*1024
for offset in range(0, file_length, BUFFER_SIZE):
chunk = self.rfile.read(min(file_length-offset, BUFFER_SIZE))
output_file.write(chunk)
target_lib.new_build(self.path[6:], file_name) target_lib.new_build(self.path[6:], file_name)
self._set_response(code=201) self._set_response(code=201)
self.wfile.write( self.wfile.write(
@@ -158,7 +161,6 @@ class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
def run_server(SeverClass=ThreadedHTTPServer, HandlerClass=RequestHandler, port=8000): def run_server(SeverClass=ThreadedHTTPServer, HandlerClass=RequestHandler, port=8000):
logging.basicConfig(level=logging.DEBUG)
server_address = (LOCAL_ADDRESS, port) server_address = (LOCAL_ADDRESS, port)
server_instance = SeverClass(server_address, HandlerClass) server_instance = SeverClass(server_address, HandlerClass)
try: try:
@@ -169,12 +171,27 @@ def run_server(SeverClass=ThreadedHTTPServer, HandlerClass=RequestHandler, port=
except KeyboardInterrupt: except KeyboardInterrupt:
pass pass
server_instance.server_close() server_instance.server_close()
logging.basicConfig(level=logging.DEBUG)
logging.info('Server has been turned off.') logging.info('Server has been turned off.')
if __name__ == '__main__': if __name__ == '__main__':
from sys import argv from sys import argv
logging.basicConfig(level=logging.DEBUG)
print(argv) print(argv)
if os.path.exists("otatools.zip"):
logging.info("Found otatools.zip, extracting...")
EXTRACT_DIR = "./"
os.makedirs(EXTRACT_DIR, exist_ok=True)
with zipfile.ZipFile("otatools.zip", "r") as zfp:
zfp.extractall(EXTRACT_DIR)
# mark all binaries executable by owner
bin_dir = os.path.join(EXTRACT_DIR, "bin")
for filename in os.listdir(bin_dir):
os.chmod(os.path.join(bin_dir, filename), stat.S_IRWXU)
os.environ["PATH"] = os.path.join(EXTRACT_DIR, "bin") + ":" + os.environ["PATH"]
logging.info("Extracted otatools to {}".format(EXTRACT_DIR))
logging.info("PATH: %s", os.environ["PATH"])
if not os.path.isdir('target'): if not os.path.isdir('target'):
os.mkdir('target', 755) os.mkdir('target', 755)
if not os.path.isdir('output'): if not os.path.isdir('output'):