diff options
author | Abhishek Pandit-Subedi <abhishekpandit@google.com> | 2022-03-31 10:08:28 -0700 |
---|---|---|
committer | Abhishek Pandit-Subedi <abhishekpandit@google.com> | 2022-03-31 10:14:18 -0700 |
commit | f05e97f5e8a444b8a9ef4c2a70ff348757be2d6c (patch) | |
tree | f084f4a02261171c034405496cc2dfabd7f24c8f /floss/build/build-in-docker.py | |
parent | 93dd6fb80931db77db6077fae6363aa1932bfaf3 (diff) |
floss: Replace docker with podman
Docker requires root permissions to run and is not preferable for
security reasons. Podman is a drop-in replacement that doesn't run as
root.
Bug: 220203992
Tag: #floss
Test: ./docker-build-image.py --tag floss:latest; ./build-in-docker.py
Change-Id: I813fb63a25bf5588560090ddfb0ad290729a4ff1
Diffstat (limited to 'floss/build/build-in-docker.py')
-rwxr-xr-x | floss/build/build-in-docker.py | 185 |
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() |