summaryrefslogtreecommitdiff
path: root/floss/build/build-in-docker.py
diff options
context:
space:
mode:
Diffstat (limited to 'floss/build/build-in-docker.py')
-rwxr-xr-xfloss/build/build-in-docker.py185
1 files changed, 0 insertions, 185 deletions
diff --git a/floss/build/build-in-docker.py b/floss/build/build-in-docker.py
deleted file mode 100755
index 774b1befdf..0000000000
--- a/floss/build/build-in-docker.py
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/usr/bin/env python3
-
-import argparse
-import os
-import subprocess
-import sys
-import time
-
-
-class FlossDockerRunner:
- """Runs Floss build inside docker container."""
-
- # Commands to run for build
- BUILD_COMMANDS = [
- # First run bootstrap to get latest code + create symlinks
- ['/root/src/build.py', '--run-bootstrap'],
-
- # Clean up any previous artifacts inside the volume
- ['/root/src/build.py', '--target', 'clean'],
-
- # Run normal code builder
- ['/root/src/build.py', '--target', 'all'],
-
- # Run tests
- ['/root/src/build.py', '--target', 'test'],
- ]
-
- def __init__(self, workdir, rootdir, image_tag, volume_name, container_name, staging_dir):
- """ Constructor.
-
- Args:
- workdir: Current working directory (should be the script path).
- rootdir: Root directory for Bluetooth.
- image_tag: Tag for docker image used for building.
- volume_name: Volume name used for storing artifacts.
- container_name: Name for running container instance.
- staging_dir: Directory to mount for artifacts instead of using volume.
- """
- self.workdir = workdir
- self.rootdir = rootdir
- self.image_tag = image_tag
- self.env = os.environ.copy()
-
- # Name of running container
- self.container_name = container_name
-
- # Name of volume to write output.
- self.volume_name = volume_name
- # Staging dir where we send output instead of the volume.
- self.staging_dir = staging_dir
-
- def run_command(self, target, args, cwd=None, env=None, ignore_rc=False):
- """ Run command and stream the output.
- """
- # Set some defaults
- if not cwd:
- cwd = self.workdir
- if not env:
- env = self.env
-
- rc = 0
- process = subprocess.Popen(args, cwd=cwd, env=env, stdout=subprocess.PIPE)
- while True:
- line = process.stdout.readline()
- print(line.decode('utf-8'), end="")
- if not line:
- rc = process.poll()
- if rc is not None:
- break
-
- time.sleep(0.1)
-
- if rc != 0 and not ignore_rc:
- raise Exception("{} failed. Return code is {}".format(target, rc))
-
- def _create_volume_if_needed(self):
- # Check if the volume exists. Otherwise create it.
- try:
- subprocess.check_output(['docker', 'volume', 'inspect', self.volume_name])
- finally:
- self.run_command('docker volume create', ['docker', 'volume', 'create', self.volume_name])
-
- def start_container(self):
- """Starts the docker container with correct mounts."""
- # Stop any previously started container.
- self.stop_container(ignore_error=True)
-
- # Create volume and create mount string
- if self.staging_dir:
- mount_output_volume = 'type=bind,src={},dst=/root/.floss'.format(self.staging_dir)
- else:
- # If not using staging dir, use the volume instead
- self._create_volume_if_needed()
- mount_output_volume = 'type=volume,src={},dst=/root/.floss'.format(self.volume_name)
-
- # Mount the source directory
- mount_src_dir = 'type=bind,src={},dst=/root/src'.format(self.rootdir)
-
- # Run the docker image. It will run `tail` indefinitely so the container
- # doesn't close and we can run `docker exec` on it.
- self.run_command('docker run', [
- 'docker', 'run', '--name', self.container_name, '--mount', mount_output_volume, '--mount', mount_src_dir,
- '-d', self.image_tag, 'tail', '-f', '/dev/null'
- ])
-
- def stop_container(self, ignore_error=False):
- """Stops the docker container for build."""
- self.run_command('docker stop', ['docker', 'stop', '-t', '1', self.container_name], ignore_rc=ignore_error)
- self.run_command('docker rm', ['docker', 'rm', self.container_name], ignore_rc=ignore_error)
-
- def do_build(self):
- """Runs the basic build commands."""
- # Start container before building
- self.start_container()
-
- try:
- # Run all commands
- for i, cmd in enumerate(self.BUILD_COMMANDS):
- self.run_command('docker exec #{}'.format(i), ['docker', 'exec', '-it', self.container_name] + cmd)
- finally:
- # Always stop container before exiting
- self.stop_container()
-
- def print_do_build(self):
- """Prints the commands for building."""
- docker_exec = ['docker', 'exec', '-it', self.container_name]
- print('Normally, build would run the following commands: \n')
- for cmd in self.BUILD_COMMANDS:
- print(' '.join(docker_exec + cmd))
-
- def check_docker_runnable(self):
- try:
- subprocess.check_output(['docker', 'ps'], stderr=subprocess.STDOUT)
- except subprocess.CalledProcessError as err:
- if 'denied' in err.output.decode('utf-8'):
- print('Run script as sudo')
- else:
- print('Unexpected error: {}'.format(err.output.decode('utf-8')))
-
- return False
-
- # No exception means docker is ok
- return True
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser('Builder Floss inside docker image.')
- parser.add_argument(
- '--only-start',
- action='store_true',
- default=False,
- help='Only start the container. Prints the commands it would have ran.')
- parser.add_argument('--only-stop', action='store_true', default=False, help='Only stop the container and exit.')
- parser.add_argument('--image-tag', default='floss:latest', help='Docker image to use to build.')
- parser.add_argument(
- '--volume-tag',
- default='floss-out',
- help='Name of volume to use. This is where build artifacts will be stored by default.')
- parser.add_argument(
- '--staging-dir',
- default=None,
- help='Staging directory to use instead of volume. Build artifacts will be written here.')
- parser.add_argument('--container-name', default='floss-docker-runner', help='What to name the started container')
- args = parser.parse_args()
-
- # cwd should be set to same directory as this script (that's where Dockerfile
- # is kept).
- workdir = os.path.dirname(os.path.abspath(sys.argv[0]))
- rootdir = os.path.abspath(os.path.join(workdir, '../..'))
-
- # Determine staging directory absolute path
- staging = os.path.abspath(args.staging_dir) if args.staging_dir else None
-
- fdr = FlossDockerRunner(workdir, rootdir, args.image_tag, args.volume_tag, args.container_name, staging)
-
- # Make sure docker is runnable before continuing
- if fdr.check_docker_runnable():
- # Handle some flags
- if args.only_start:
- fdr.start_container()
- fdr.print_do_build()
- elif args.only_stop:
- fdr.stop_container()
- else:
- fdr.do_build()