def test_timeout_build(self): pings = 3 p0 = MockProcess(limit_lines=pings, sleep_time=1) output = io.BytesIO() read_with_timeout(p0, output, timeout=0.5) out = output.getvalue() self.assertIn(b'\nTimeout', out)
def test_timeout_build(self): pings = 3 p0 = MockProcess(limit_lines=pings, sleep_time=1) output = io.BytesIO() read_with_timeout(p0, output, timeout=0.5) out = output.getvalue() self.assertIn(b'\nTimeout', out)
def test_good_build(self): """ reads a process that takes 3s to complete, with 60s timeout """ pings = 3 p0 = MockProcess(limit_lines=pings) output = io.BytesIO() read_with_timeout(p0, output) self.assertFalse(p0.output.timed_out) self.assertEqual(pings, output.getvalue().count(b'ping'))
def test_good_build(self): """ reads a process that takes 3s to complete, with 60s timeout """ pings = 3 p0 = MockProcess(limit_lines=pings) output = io.BytesIO() read_with_timeout(p0, output) self.assertFalse(p0.output.timed_out) self.assertEqual(pings, output.getvalue().count(b'ping'))
def test_user_terminated_build(self): def terminate(count=[]): count.append(None) return len(count) >= 3 pings = 30 p0 = MockProcess(limit_lines=pings, sleep_time=0.1) output = io.BytesIO() read_with_timeout(p0, output, build_was_stopped_by_user=terminate) out = output.getvalue() self.assertIn(b'User requested', out)
def test_iotimeout_build_1(self): """ reads a process that takes 1.5s to complete, with 0.5s timeout """ pings = 3 p0 = MockProcess(limit_lines=pings, sleep_time=3) output = io.BytesIO() read_with_timeout(p0, output, iotimeout=0.5) self.assertTrue(p0.output.timed_out) out = output.getvalue() self.assertIn(b'iotimeout', out)
def test_user_terminated_build(self): def terminate(count=[]): count.append(None) return len(count) >= 3 pings = 30 p0 = MockProcess(limit_lines=pings, sleep_time=0.1) output = io.BytesIO() read_with_timeout(p0, output, build_was_stopped_by_user=terminate) out = output.getvalue() self.assertIn(b'User requested', out)
def test_iotimeout_build_1(self): """ reads a process that takes 1.5s to complete, with 0.5s timeout """ pings = 3 p0 = MockProcess(limit_lines=pings, sleep_time=3) output = io.BytesIO() read_with_timeout(p0, output, iotimeout=0.5) self.assertTrue(p0.output.timed_out) out = output.getvalue() self.assertIn(b'iotimeout', out)
def test_quiet(self): for quiet in (True, False): cmd = ['echo', 'ncurses-5.9-1. 9% |## | ETA: 0:00:00 76.02 MB/s\r'] if os.name == 'nt': cmd = ['cmd.exe', '/c'] + cmd p0 = BuildProcess(cmd, '.') output = io.BytesIO() read_with_timeout(p0, output, timeout=20, quiet=quiet) out = output.getvalue() if quiet: self.assertEqual(b'', out) else: self.assertIn(b'ncurses', out)
def test_quiet(self): for quiet in (True, False): cmd = [ 'echo', 'ncurses-5.9-1. 9% |## | ETA: 0:00:00 76.02 MB/s\r' ] if os.name == 'nt': cmd = ['cmd.exe', '/c'] + cmd p0 = BuildProcess(cmd, '.') output = io.BytesIO() read_with_timeout(p0, output, timeout=20, quiet=quiet) out = output.getvalue() if quiet: self.assertEqual(b'', out) else: self.assertIn(b'ncurses', out)
def run(self, build_data, script_filename, build_log, timeout, iotimeout, api_token=None, git_oauth_token=None, build_filename=None, instructions=None, build_was_stopped_by_user=lambda: None): """ """ cli = self.client image = self.args.image container_script_filename = '/{0}'.format(basename(script_filename)) volumes = [ container_script_filename, ] binds = { abspath(script_filename): { 'bind': container_script_filename, 'ro': False } } args = ["bash", container_script_filename, '--api-token', api_token] if git_oauth_token: args.extend(['--git-oauth-token', git_oauth_token]) elif build_filename: container_build_filename = '/{0}'.format(basename(build_filename)) volumes.append(container_build_filename) binds[build_filename] = { 'bind': container_build_filename, 'ro': False } args.extend(['--build-tarball', container_build_filename]) log.info("Running command: (iotimeout={0})".format(iotimeout)) if self.args.allow_user_images: if instructions and instructions.get('docker_image'): image = instructions['docker_image'] if ':' in image: repository, tag = image.rsplit(':', 1) else: repository, tag = image, None build_log.write('Docker: Pull {0}\n'.format(image)) for line in cli.pull(repository, tag=tag, stream=True): msg = json.loads(line) if msg.get('status') == 'Downloading': build_log.write('.') elif msg.get('status'): build_log.write(msg.get('status', '') + '\n') else: build_log.write(line + '\n') else: if instructions and instructions.get('docker_image'): build_log.write( "WARNING: User specified images are not allowed on this build worker\n" ) build_log.write("Using default docker image\n") command = " ".join(args) log.info(command) build_log.write("Docker Image: {0}\n".format(image).encode('utf8')) log.info("Volumes: {0}".format(volumes)) build_log.write(b"Docker: Create container\n") cont = cli.create_container(image, command=command, volumes=volumes) build_log.write(b"Docker: Attach output\n") build_log.write(b"Docker: Start\n") p0 = DockerBuildProcess(cli, cont) log.info("Binds: {0}".format(binds)) cli.start(cont, binds=binds) # ios = IOStream(stream, build_log, iotimeout, timeout, timeout_callback) try: read_with_timeout(p0, build_log, timeout, iotimeout, BuildLog.INTERVAL, build_was_stopped_by_user) except BaseException: log.error( "Binstar build process caught an exception while waiting for the build to finish" ) p0.kill() p0.wait() p0.remove() raise exit_code = p0.wait() log.info("Remove Container: {0}".format(cont)) cli.remove_container(cont, v=True) return exit_code
def run(self, build_data, script_filename, build_log, timeout, iotimeout, api_token=None, git_oauth_token=None, build_filename=None, instructions=None, build_was_stopped_by_user=lambda: None): log.info("Running build script") working_dir = self.working_dir(build_data) args = [os.path.abspath(script_filename), '--api-token', api_token] if git_oauth_token: args.extend(['--git-oauth-token', git_oauth_token]) elif build_filename: args.extend(['--build-tarball', build_filename]) log.info("Running command: (iotimeout={0})".format(iotimeout)) log.info(" ".join(args)) if self.args.show_new_procs: already_running_procs = get_my_procs() p0 = process_wrappers.BuildProcess(args, cwd=working_dir) log.info("Started build script with pid: {}".format(p0.pid)) try: read_with_timeout( p0, build_log, timeout, iotimeout, BuildLog.INTERVAL, build_was_stopped_by_user, ) except BaseException: log.error( "Anaconda build process caught an exception while waiting for the build to finish" ) p0.kill() p0.wait() raise finally: if self.args.show_new_procs: currently_running_procs = get_my_procs() new_procs = [ psutil.Process(pid) for pid in currently_running_procs - already_running_procs ] if new_procs: build_log.write( "WARNING: There are processes that were started during the build and are" "still running\n") for proc in new_procs: build_log.write( " - Process name: {0} pid:{1}\n".format( proc.name, proc.pid)) try: cmdline = ' '.join(proc.cmdline) except: pass else: build_log.write(" + {0}\n".format(cmdline)) return p0.poll()
def run(self, build_data, script_filename, build_log, timeout, iotimeout, api_token=None, git_oauth_token=None, build_filename=None, instructions=None, build_was_stopped_by_user=lambda:None): log.info("Running build script") working_dir = self.working_dir(build_data) args = [os.path.abspath(script_filename), '--api-token', api_token] if git_oauth_token: args.extend(['--git-oauth-token', git_oauth_token]) elif build_filename: args.extend(['--build-tarball', build_filename]) quiet = build_data['build_item_info'].get('instructions',{}).get('quiet', False) log.info("Running command: (iotimeout={0})".format(iotimeout)) log.info(" ".join(args)) if self.args.show_new_procs: already_running_procs = get_my_procs() p0 = process_wrappers.BuildProcess( args, cwd=working_dir ) log.info("Started build script with pid: {}".format(p0.pid)) try: read_with_timeout( p0, build_log, timeout, iotimeout, BuildLog.INTERVAL, build_was_stopped_by_user, quiet ) except BaseException: log.error( "Binstar build process caught an exception while waiting for the build to" "finish") p0.kill() p0.wait() raise finally: if self.args.show_new_procs: currently_running_procs = get_my_procs() new_procs = [ psutil.Process(pid) for pid in currently_running_procs - already_running_procs] if new_procs: build_log.write( "WARNING: There are processes that were started during the build and are" "still running\n") for proc in new_procs: build_log.write(" - Process name: {0} pid:{1}\n".format( proc.name, proc.pid)) try: cmdline = ' '.join(proc.cmdline) except: pass else: build_log.write(" + {0}\n".format(cmdline)) return p0.poll()
def run(self, build_data, script_filename, build_log, timeout, iotimeout, api_token=None, git_oauth_token=None, build_filename=None, instructions=None, build_was_stopped_by_user=lambda:None): """ """ cli = self.client image = self.args.image container_script_filename = '/{0}'.format(basename(script_filename)) volumes = [container_script_filename, ] binds = {abspath(script_filename): {'bind': container_script_filename, 'ro': False}} args = ["bash", container_script_filename, '--api-token', api_token] if git_oauth_token: args.extend(['--git-oauth-token', git_oauth_token]) elif build_filename: container_build_filename = '/{0}'.format(basename(build_filename)) volumes.append(container_build_filename) binds[build_filename] = {'bind': container_build_filename, 'ro': False} args.extend(['--build-tarball', container_build_filename]) log.info("Running command: (iotimeout={0})".format(iotimeout)) if self.args.allow_user_images: if instructions and instructions.get('docker_image'): image = instructions['docker_image'] if ':' in image: repository, tag = image.rsplit(':', 1) else: repository, tag = image, None build_log.write('Docker: Pull {0}\n'.format(image)) for line in cli.pull(repository, tag=tag, stream=True): msg = json.loads(line) if msg.get('status') == 'Downloading': build_log.write('.') elif msg.get('status'): build_log.write(msg.get('status', '') + '\n') else: build_log.write(line + '\n') else: if instructions and instructions.get('docker_image'): build_log.write("WARNING: User specified images are not allowed on this build worker\n") build_log.write("Using default docker image\n") command = " ".join(args) log.info(command) build_log.write("Docker Image: {0}\n".format(image).encode('utf8')) log.info("Volumes: {0}".format(volumes)) build_log.write(b"Docker: Create container\n") cont = cli.create_container(image, command=command, volumes=volumes) build_log.write(b"Docker: Attach output\n") build_log.write(b"Docker: Start\n") p0 = DockerBuildProcess(cli, cont) log.info("Binds: {0}".format(binds)) cli.start(cont, binds=binds) # ios = IOStream(stream, build_log, iotimeout, timeout, timeout_callback) try: read_with_timeout( p0, build_log, timeout, iotimeout, BuildLog.INTERVAL, build_was_stopped_by_user ) except BaseException: log.error("Binstar build process caught an exception while waiting for the build to finish") p0.kill() p0.wait() p0.remove() raise exit_code = p0.wait() log.info("Remove Container: {0}".format(cont)) cli.remove_container(cont, v=True) return exit_code
def run(self, build_data, script_filename, build_log, timeout, iotimeout, api_token=None, git_oauth_token=None, build_filename=None, instructions=None, build_was_stopped_by_user=lambda:None): """ """ cli = self.client image = self.args.image script_basename = basename(script_filename) # files to transfer into the working directory of the image transfer_files = [(script_filename, script_basename)] # TODO: working_dir should probably be extracted from the docker image definition (WORKDIR) working_dir = self.working_dir(build_data) container_script_filename = '{0}/{1}'.format(working_dir, script_basename) args = ["bash", container_script_filename, '--api-token', api_token] if git_oauth_token: args.extend(['--git-oauth-token', git_oauth_token]) elif build_filename: build_basename = basename(build_filename) container_build_filename = '{0}/{1}'.format(working_dir, build_basename) args.extend(['--build-tarball', container_build_filename]) transfer_files.append((build_filename, build_basename)) log.info("Running command: (iotimeout={0})".format(iotimeout)) if self.args.allow_user_images: if instructions and instructions.get('docker_image'): image = instructions['docker_image'] if ':' in image: repository, tag = image.rsplit(':', 1) else: repository, tag = image, None build_log.writeline(b'Docker: Pull {0}\n'.format(image)) for index, line in enumerate(cli.pull(repository, tag=tag, stream=True)): msg = json.loads(line) if msg.get('status') == 'Downloading': build_log.writeline(b'.' * index + '\r') elif msg.get('status'): build_log.writeline(msg.get('status', '').encode('utf-8', 'replace') + b'\n') else: build_log.writeline(line.encode('utf-8', 'replace') + b'\n') else: if instructions and instructions.get('docker_image'): build_log.writeline(b"WARNING: User specified images are not allowed on this build worker\n") build_log.writeline(b"Using default docker image\n") command = " ".join(args) log.info("Executing '%s' on docker", command) build_log.writeline("Docker Image: {0}\n".format(image).encode('utf8')) build_log.writeline(b"Docker: Create container\n") cont = cli.create_container(image, command=command) build_log.writeline(b"Docker: Attach output\n") archive = BytesIO() with tarfile.open(fileobj=archive, mode='w') as tf: for filename, arcname in transfer_files: tf.add(filename, arcname) archive.seek(0) put_success = cli.put_archive(cont, working_dir, archive) # build_log.write(b"Docker: Inserted script: %s\n" % put_success) build_log.writeline(b"Docker: Start\n") p0 = DockerBuildProcess(cli, cont) cli.start(cont) try: read_with_timeout( p0, build_log, timeout, iotimeout, BuildLog.INTERVAL, build_was_stopped_by_user ) except BaseException: log.error("Binstar build process caught an exception while waiting for the build to finish") p0.kill() p0.wait() p0.remove() raise exit_code = p0.wait() log.info("Remove Container: {0}".format(cont)) cli.remove_container(cont, v=True) return exit_code
def run(self, build_data, script_filename, build_log, timeout, iotimeout, api_token=None, git_oauth_token=None, build_filename=None, instructions=None, build_was_stopped_by_user=lambda: None): """ """ cli = self.client image = self.args.image script_basename = basename(script_filename) # files to transfer into the working directory of the image transfer_files = [(script_filename, script_basename)] # TODO: working_dir should probably be extracted from the docker image definition (WORKDIR) working_dir = self.working_dir(build_data) container_script_filename = '{0}/{1}'.format(working_dir, script_basename) args = ["bash", container_script_filename, '--api-token', api_token] if git_oauth_token: args.extend(['--git-oauth-token', git_oauth_token]) elif build_filename: build_basename = basename(build_filename) container_build_filename = '{0}/{1}'.format( working_dir, build_basename) args.extend(['--build-tarball', container_build_filename]) transfer_files.append((build_filename, build_basename)) log.info("Running command: (iotimeout={0})".format(iotimeout)) if self.args.allow_user_images: if instructions and instructions.get('docker_image'): image = instructions['docker_image'] if ':' in image: repository, tag = image.rsplit(':', 1) else: repository, tag = image, None build_log.writeline(b'Docker: Pull {0}\n'.format(image)) for index, line in enumerate( cli.pull(repository, tag=tag, stream=True)): msg = json.loads(line) if msg.get('status') == 'Downloading': build_log.writeline(b'.' * index + '\r') elif msg.get('status'): build_log.writeline( msg.get('status', '').encode('utf-8', 'replace') + b'\n') else: build_log.writeline( line.encode('utf-8', 'replace') + b'\n') else: if instructions and instructions.get('docker_image'): build_log.writeline( b"WARNING: User specified images are not allowed on this build worker\n" ) build_log.writeline(b"Using default docker image\n") command = " ".join(args) log.info("Executing '%s' on docker", command) build_log.writeline("Docker Image: {0}\n".format(image).encode('utf8')) build_log.writeline(b"Docker: Create container\n") cont = cli.create_container(image, command=command) build_log.writeline(b"Docker: Attach output\n") archive = BytesIO() with tarfile.open(fileobj=archive, mode='w') as tf: for filename, arcname in transfer_files: tf.add(filename, arcname) archive.seek(0) put_success = cli.put_archive(cont, working_dir, archive) # build_log.write(b"Docker: Inserted script: %s\n" % put_success) build_log.writeline(b"Docker: Start\n") p0 = DockerBuildProcess(cli, cont) cli.start(cont) try: read_with_timeout(p0, build_log, timeout, iotimeout, BuildLog.INTERVAL, build_was_stopped_by_user) except BaseException: log.error( "Binstar build process caught an exception while waiting for the build to finish" ) p0.kill() p0.wait() p0.remove() raise exit_code = p0.wait() log.info("Remove Container: {0}".format(cont)) cli.remove_container(cont, v=True) return exit_code