def command(shell, args): # get installed commands installed = set(shell.commands.keys()) # get list of commands to uninstall / not-uninstallable requested_to_uninstall = set(args) to_uninstall = requested_to_uninstall.intersection(installed) not_uninstallable = requested_to_uninstall.difference(installed) need_reload = False # not uninstallable for cmd in not_uninstallable: dtslogger.warn('The command `%s` cannot be found.' % cmd) # uninstall for cmd in to_uninstall: dtslogger.info('Removing command `%s`...' % cmd) shell.disable_command(cmd) need_reload = True dtslogger.info('Successfully completed calibration!') print('Done!') # update list of commands if need_reload: print('Updating index...') shell.reload_commands() print('Done!') else: print('Nothing to do.') return True
def run_image_on_duckiebot(image_name, duckiebot_name, env=None, volumes=None): duckiebot_ip = get_duckiebot_ip(duckiebot_name) duckiebot_client = get_remote_client(duckiebot_ip) env_vars = default_env(duckiebot_name, duckiebot_ip) if env is not None: env_vars.update(env) dtslogger.info("Running %s with environment: %s" % (image_name, env_vars)) params = { 'image': image_name, 'remove': True, 'network_mode': 'host', 'privileged': True, 'detach': True, 'environment': env_vars } if volumes is not None: params['volumes'] = volumes # Make sure we are not already running the same image if all(elem.image != image_name for elem in duckiebot_client.containers.list()): return duckiebot_client.containers.run(**params) else: dtslogger.warn( 'Container with image %s is already running on %s, skipping...' % (image_name, duckiebot_name))
def remove_if_running(client, container_name): try: container = client.containers.get(container_name) dtslogger.info("%s already running - stopping it first.." % container_name) stop_container(container) dtslogger.info("removing %s" % container_name) remove_container(container) except Exception as e: dtslogger.warn("couldn't remove existing container: %s" % e)
def command(shell, args): if shell.commands_path_leave_alone: dtslogger.warn( 'Will not update the commands because the path was set explicitly.' ) else: if shell.update_commands(): dtslogger.info('Duckietown Shell commands updated.') else: dtslogger.error('Update was not successful.')
def run_gui_controller(hostname, image): client = check_docker_environment() container_name = "joystick_gui_%s" % hostname remove_if_running(client, container_name) duckiebot_ip = get_duckiebot_ip(hostname) env = { 'HOSTNAME': hostname, 'ROS_MASTER': hostname, 'DUCKIEBOT_NAME': hostname, 'ROS_MASTER_URI': 'http://%s:11311' % duckiebot_ip } env['QT_X11_NO_MITSHM'] = 1 volumes = {} subprocess.call(["xhost", "+"]) p = platform.system().lower() if 'darwin' in p: dtslogger.warn( "We can try but running the joystick gui on MacOSx is not expected to work..." ) env['DISPLAY'] = 'host.docker.internal:0' volumes = {'/tmp/.X11-unix': {'bind': '/tmp/.X11-unix', 'mode': 'rw'}} else: env['DISPLAY'] = os.environ['DISPLAY'] dtslogger.info("Running %s on localhost with environment vars: %s" % (container_name, env)) if 'master19' in image: image = "duckietown/rpi-duckiebot-base:master19-no-arm" cmd = "python misc/virtualJoy/virtualJoy.py %s" % hostname elif 'daffy' in image: image = "duckietown/dt-core:daffy-amd64" cmd = "roslaunch virtual_joystick virtual_joystick_gui.launch veh:=%s" % hostname params = { 'image': image, 'name': container_name, 'network_mode': 'host', 'environment': env, 'privileged': True, 'stdin_open': True, 'tty': True, 'command': cmd, 'detach': True, 'volumes': volumes } container = client.containers.run(**params) cmd = 'docker attach %s' % container_name start_command_in_subprocess(cmd)
def run_image_on_localhost(image_name, duckiebot_name, container_name, env=None, volumes=None): duckiebot_ip = get_duckiebot_ip(duckiebot_name) local_client = check_docker_environment() env_vars = default_env(duckiebot_name, duckiebot_ip) if env is not None: env_vars.update(env) try: container = local_client.containers.get(container_name) dtslogger.info("an image already on localhost - stopping it first..") stop_container(container) remove_container(container) except Exception as e: dtslogger.warn("coulgn't remove existing container: %s" % e) dtslogger.info("Running %s on localhost with environment vars: %s" % (image_name, env_vars)) params = { 'image': image_name, 'remove': True, 'network_mode': 'host', 'privileged': True, 'detach': True, 'tty': True, 'name': container_name, 'environment': env_vars } if volumes is not None: params['volumes'] = volumes new_local_container = local_client.containers.run(**params) return new_local_container
def command(shell, args): prog = 'dts duckiebot calibrate_extrinsics DUCKIEBOT_NAME' usage = """ Calibrate: %(prog)s """ parser = argparse.ArgumentParser(prog=prog, usage=usage) parser.add_argument('hostname', default=None, help='Name of the Duckiebot to calibrate') parser.add_argument('--base_image', dest='image', default="duckietown/rpi-duckiebot-base:master19") parser.add_argument( '--no_verification', action='store_true', default=False, help="If you don't have a lane you can skip the verificaiton step") parsed_args = parser.parse_args(args) hostname = parsed_args.hostname duckiebot_ip = get_duckiebot_ip(hostname) duckiebot_client = get_remote_client(duckiebot_ip) calibration_container_name = "extrinsic_calibration" validation_container_name = "extrinsic_calibration_validation" remove_if_running(duckiebot_client, calibration_container_name) remove_if_running(duckiebot_client, validation_container_name) # need to temporarily pause the image streaming from the robot try: duckiebot_containers = duckiebot_client.containers.list() interface_container_found = False for c in duckiebot_containers: if 'duckiebot-interface' in c.name: interface_container_found = True interface_container = c dtslogger.info("Temporarily stopping image streaming...") interface_container.stop() except Exception as e: dtslogger.warn( "Not sure if the duckiebot-interface is running because we got and exception when trying: %s" % e) image = parsed_args.image timestamp = datetime.date.today().strftime('%Y%m%d%H%M%S') raw_input( "{}\nPlace the Duckiebot on the calibration patterns and press ENTER." .format('*' * 20)) log_file = 'out-calibrate-extrinsics-%s-%s' % (hostname, timestamp) rosrun_params = '-o /data/{0} > /data/{0}.log'.format(log_file) ros_pkg = 'complete_image_pipeline calibrate_extrinsics' start_command = 'rosrun {0} {1}'.format(ros_pkg, rosrun_params) dtslogger.info('Running command: {}'.format(start_command)) env = default_env(hostname, duckiebot_ip) duckiebot_client.containers.run(image=image, name=calibration_container_name, privileged=True, network_mode='host', volumes=bind_duckiebot_data_dir(), command="/bin/bash -c '%s'" % start_command, environment=env) if not parsed_args.no_verification: raw_input( "{}\nPlace the Duckiebot in a lane and press ENTER.".format( '*' * 20)) log_file = 'out-pipeline-%s-%s' % (hostname, timestamp) rosrun_params = '-o /data/{0} > /data/{0}.log'.format(log_file) ros_pkg = 'complete_image_pipeline single_image_pipeline' start_command = 'rosrun {0} {1}'.format(ros_pkg, rosrun_params) dtslogger.info('Running command: {}'.format(start_command)) duckiebot_client.containers.run(image=image, name=validation_container_name, privileged=True, network_mode='host', volumes=bind_duckiebot_data_dir(), command="/bin/bash -c '%s'" % start_command, environment=env) # restart the camera streaming try: all_duckiebot_containers = duckiebot_client.containers.list( all=True) found = False for c in all_duckiebot_containers: if 'duckiebot-interface' in c.name: found = True dtslogger.info("Restarting image streaming...") c.start() except Exception as e: dtslogger.warn( "Not sure if the duckiebot-interface is running because we got and exception when trying: %s" % e)
def command(shell, args): prog = 'dts duckiebot calibrate_intrinsics DUCKIEBOT_NAME' usage = """ Calibrate: %(prog)s """ parser = argparse.ArgumentParser(prog=prog, usage=usage) parser.add_argument('hostname', default=None, help='Name of the Duckiebot to calibrate') parser.add_argument('--base_image', dest='image', default="duckietown/rpi-duckiebot-base:master19-no-arm") parser.add_argument('--debug', action='store_true', default=False, help="will enter you into the running container") parsed_args = parser.parse_args(args) hostname = parsed_args.hostname duckiebot_ip = get_duckiebot_ip(hostname) duckiebot_client = get_remote_client(duckiebot_ip) # is the interface running? try: duckiebot_containers = duckiebot_client.containers.list() interface_container_found = False for c in duckiebot_containers: if 'duckiebot-interface' in c.name: interface_container_found = True if not interface_container_found: dtslogger.error("The duckiebot-interface is not running on the duckiebot") exit() except Exception as e: dtslogger.warn( "Not sure if the duckiebot-interface is running because we got and exception when trying: %s" % e) # is the raw imagery being published? try: duckiebot_containers = duckiebot_client.containers.list() raw_imagery_found = False for c in duckiebot_containers: if 'demo_camera' in c.name: raw_imagery_found = True if not raw_imagery_found: dtslogger.error("The demo_camera is not running on the duckiebot - please run `dts duckiebot demo --demo_name camera --duckiebot_name %s" % hostname) exit() except Exception as e: dtslogger.warn("%s" % e) image = parsed_args.image client = check_docker_environment() container_name = "intrinsic_calibration_%s" % hostname remove_if_running(client,container_name) env = {'HOSTNAME': hostname, 'ROS_MASTER': hostname, 'DUCKIEBOT_NAME': hostname, 'ROS_MASTER_URI': 'http://%s:11311' % duckiebot_ip, 'QT_X11_NO_MITSHM': 1} volumes = {} subprocess.call(["xhost", "+"]) p = platform.system().lower() if 'darwin' in p: env['DISPLAY'] = 'host.docker.internal:0' volumes = { '/tmp/.X11-unix': {'bind': '/tmp/.X11-unix', 'mode': 'rw'} } else: env['DISPLAY'] = os.environ['DISPLAY'] dtslogger.info("Running %s on localhost with environment vars: %s" % (container_name, env)) dtslogger.info("When the window opens you will need to move the checkerboard around in front of the Duckiebot camera") cmd = "roslaunch pi_camera intrinsic_calibration.launch veh:=%s" % hostname params = {'image': image, 'name': container_name, 'network_mode': 'host', 'environment': env, 'privileged': True, 'stdin_open': True, 'tty': True, 'detach': True, 'command': cmd, 'volumes': volumes } container = client.containers.run(**params) if parsed_args.debug: attach_cmd = 'docker attach %s' % (container_name) start_command_in_subprocess(attach_cmd)
def command(shell, args): prog = 'dts duckiebot evaluate' parser = argparse.ArgumentParser(prog=prog, usage=usage) group = parser.add_argument_group('Basic') group.add_argument('--duckiebot_name', default=None, help="Name of the Duckiebot on which to perform evaluation") group.add_argument('--duckiebot_username', default="duckie", help="The duckiebot username") group.add_argument('--image', dest='image_name', help="Image to evaluate, if none specified then we will build your current context", default=None) group.add_argument('--glue_node_image', default="duckietown/challenge-aido_lf-duckiebot:aido2", help="The node that glues your submission with ROS on the duckiebot. Probably don't change") group.add_argument('--duration', help="Number of seconds to run evaluation", default=15) group.add_argument('--remotely', action='store_true', default=True, help="If true run the image over network without pushing to Duckiebot") group.add_argument('--no_cache', help="disable cache on docker build", action="store_true", default=False) group.add_argument('--record_bag', action='store_true', default=False, help="If true record a rosbag") group.add_argument("--debug", action='store_true', default=False, help="If true you will get a shell instead of executing") group.add_argument('--max_vel', help="the max velocity for the duckiebot", default=0.7) group.add_argument('--challenge', help="Specific challenge to evaluate") parsed = parser.parse_args(args) tmpdir = '/tmp' USERNAME = getpass.getuser() dir_home_guest = os.path.expanduser('~') dir_fake_home = os.path.join(tmpdir, 'fake-%s-home' % USERNAME) if not os.path.exists(dir_fake_home): os.makedirs(dir_fake_home) get_calibration_files(dir_fake_home, parsed.duckiebot_username, parsed.duckiebot_name) client = check_docker_environment() agent_container_name = "agent" glue_container_name = "aido_glue" # remove the containers if they are already running remove_if_running(client, agent_container_name) remove_if_running(client, glue_container_name) # setup the fifos2 volume (requires pruning it if it's still hanging around from last time) try: client.volumes.prune() fifo2_volume=client.volumes.create(name='fifos2') except Exception as e: dtslogger.warn("error creating volume: %s" % e) duckiebot_ip = get_duckiebot_ip(parsed.duckiebot_name) duckiebot_client = get_remote_client(duckiebot_ip) try: duckiebot_containers = duckiebot_client.containers.list() interface_container_found=False for c in duckiebot_containers: if 'duckiebot-interface' in c.name: interface_container_found=True if not interface_container_found: dtslogger.error("The duckiebot-interface is not running on the duckiebot") except Exception as e: dtslogger.warn("Not sure if the duckiebot-interface is running because we got and exception when trying: %s" % e) # let's start building stuff for the "glue" node glue_volumes = {fifo2_volume.name: {'bind': '/fifos', 'mode': 'rw'}} glue_env = {'HOSTNAME':parsed.duckiebot_name, 'DUCKIEBOT_NAME':parsed.duckiebot_name, 'ROS_MASTER_URI':'http://%s:11311' % duckiebot_ip} dtslogger.info("Running %s on localhost with environment vars: %s" % (parsed.glue_node_image, glue_env)) params = {'image': parsed.glue_node_image, 'name': glue_container_name, 'network_mode': 'host', 'privileged': True, 'environment': glue_env, 'detach': True, 'tty': True, 'volumes': glue_volumes} # run the glue container glue_container = client.containers.run(**params) if not parsed.debug: monitor_thread = threading.Thread(target=continuously_monitor, args=(client, glue_container.name)) monitor_thread.start() if parsed.image_name is None: # if we didn't get an `image_name` we try need to build the local container path = '.' dockerfile = os.path.join(path, 'Dockerfile') if not os.path.exists(dockerfile): msg = 'No Dockerfile' raise Exception(msg) tag='myimage' if parsed.no_cache: cmd = ['docker', 'build', '--no-cache', '-t', tag, '-f', dockerfile] else: cmd = ['docker', 'build', '-t', tag, '-f', dockerfile] dtslogger.info("Running command: %s" % cmd) cmd.append(path) subprocess.check_call(cmd) image_name = tag else: image_name = parsed.image_name # start to build the agent stuff agent_env = {'AIDONODE_DATA_IN':'/fifos/agent-in', 'AIDONODE_DATA_OUT':'fifo:/fifos/agent-out'} agent_volumes = {fifo2_volume.name: {'bind': '/fifos', 'mode': 'rw'}, dir_fake_home: {'bind': '/data/config', 'mode': 'rw'} } params = {'image': image_name, 'remove': True, 'name': agent_container_name, 'environment': agent_env, 'detach': True, 'tty': True, 'volumes': agent_volumes} if parsed.debug: params['command'] = '/bin/bash' params['stdin_open'] = True dtslogger.info("Running %s on localhost with environment vars: %s" % (image_name, agent_env)) agent_container = client.containers.run(**params) if parsed.debug: attach_cmd = 'docker attach %s' % agent_container_name start_command_in_subprocess(attach_cmd) else: monitor_thread = threading.Thread(target=continuously_monitor,args=(client, agent_container_name)) monitor_thread.start() duration = int(parsed.duration) # should we record a bag? if parsed.record_bag: bag_container = record_bag(parsed.hostname, duration) dtslogger.info("Running for %d s" % duration) time.sleep(duration) stop_container(glue_container) stop_container(agent_container) if parsed.record_bag: stop_container(bag_container)
def command(shell, args): # configure arguments parser = argparse.ArgumentParser() parser.add_argument('-C', '--workdir', default=None, help="Directory containing the project to build") parser.add_argument('-a', '--arch', default=DEFAULT_ARCH, choices=set(CANONICAL_ARCH.values()), help="Target architecture for the image to build") parser.add_argument( '-H', '--machine', default=DEFAULT_MACHINE, help="Docker socket or hostname where to build the image") parser.add_argument( '--pull', default=False, action='store_true', help="Whether to pull the latest base image used by the Dockerfile" ) parser.add_argument('--no-cache', default=False, action='store_true', help="Whether to use the Docker cache") parser.add_argument( '--no-multiarch', default=False, action='store_true', help="Whether to disable multiarch support (based on bin_fmt)") parser.add_argument( '-f', '--force', default=False, action='store_true', help="Whether to force the build when the git index is not clean") parser.add_argument('--push', default=False, action='store_true', help="Whether to push the resulting image") parser.add_argument( '--rm', default=False, action='store_true', help= "Whether to remove the images once the build succeded (after pushing)" ) parser.add_argument( '--loop', default=False, action='store_true', help= "(Experimental) Whether to reuse the same base image to speed up the build process" ) parser.add_argument( '--ignore-watchtower', default=False, action='store_true', help="Whether to ignore a running Docker watchtower") parsed, _ = parser.parse_known_args(args=args) # --- code_dir = parsed.workdir if parsed.workdir else os.getcwd() dtslogger.info('Project workspace: {}'.format(code_dir)) # show info about project shell.include.devel.info.command(shell, args) # get info about current repo repo_info = shell.include.devel.info.get_repo_info(code_dir) repo = repo_info['REPOSITORY'] branch = repo_info['BRANCH'] nmodified = repo_info['INDEX_NUM_MODIFIED'] nadded = repo_info['INDEX_NUM_ADDED'] # check if the index is clean if nmodified + nadded > 0: dtslogger.warning( 'Your index is not clean (some files are not committed).') dtslogger.warning( 'If you know what you are doing, use --force (-f) to force the execution of the command.' ) if not parsed.force: exit(1) dtslogger.warning('Forced!') # create defaults default_tag = "duckietown/%s:%s" % (repo, branch) tag = "%s-%s" % (default_tag, parsed.arch) # get info about docker endpoint dtslogger.info('Retrieving info about Docker endpoint...') epoint = _run_cmd([ 'docker', '-H=%s' % parsed.machine, 'info', '--format', '{{json .}}' ], get_output=True, print_output=False) epoint = json.loads(epoint[0]) if 'ServerErrors' in epoint: dtslogger.error('\n'.join(epoint['ServerErrors'])) return epoint['MemTotal'] = _sizeof_fmt(epoint['MemTotal']) print(DOCKER_INFO.format(**epoint)) # check if there is a watchtower instance running on the endpoint if shell.include.devel.watchtower.is_running(parsed.machine): dtslogger.warning( 'An instance of a Docker watchtower was found running on the Docker endpoint.' ) dtslogger.warning( 'Building new images next to an active watchtower might (sure it will) create race conditions.' ) dtslogger.warning('Solutions:') dtslogger.warning( ' - Recommended: Use the command `dts devel watchtower stop [options]` to stop the watchtower.' ) dtslogger.warning( ' - NOT Recommended: Use the flag `--ignore-watchtower` to ignore this warning and continue.' ) if not parsed.ignore_watchtower: exit(2) dtslogger.warning('Ignored!') # print info about multiarch msg = 'Building an image for {} on {}.'.format(parsed.arch, epoint['Architecture']) dtslogger.info(msg) # register bin_fmt in the target machine (if needed) if not parsed.no_multiarch: if epoint['Architecture'] not in ARCH_MAP[CANONICAL_ARCH[ parsed.arch]]: dtslogger.info('Configuring machine for multiarch builds...') try: _run_cmd([ 'docker', '-H=%s' % parsed.machine, 'run', '--rm', '--privileged', 'multiarch/qemu-user-static:register', '--reset' ], True) dtslogger.info('Multiarch Enabled!') except: msg = 'Multiarch cannot be enabled on the target machine. This might create issues.' dtslogger.warning(msg) else: msg = 'Building an image for {} on {}. Multiarch not needed!'.format( parsed.arch, epoint['Architecture']) dtslogger.info(msg) # define labels buildlabels = [] # define build args buildargs = ['--build-arg', 'ARCH={}'.format(parsed.arch)] # loop mode (Experimental) if parsed.loop: buildargs += ['--build-arg', 'BASE_IMAGE={}'.format(repo)] buildargs += [ '--build-arg', 'BASE_TAG={}-{}'.format(branch, parsed.arch) ] buildlabels += ['--label', 'LOOP=1'] # --- msg = "WARNING: Experimental mode 'loop' is enabled!. Use with caution" dtslogger.warn(msg) # build buildlog = _run_cmd([ 'docker', '-H=%s' % parsed.machine, 'build', '--pull=%d' % int(parsed.pull), '--no-cache=%d' % int(parsed.no_cache), '-t', tag] + \ buildlabels + \ buildargs + [ code_dir ], True, True) # get image history historylog = _run_cmd([ 'docker', '-H=%s' % parsed.machine, 'history', '-H=false', '--format', '{{.ID}}:{{.Size}}', tag ], True) historylog = [l.split(':') for l in historylog if len(l.strip()) > 0] # run docker image analysis ImageAnalyzer.process(buildlog, historylog, codens=100) # image tagging if parsed.arch == DEFAULT_ARCH: dtslogger.info("Tagging image {} as {}.".format(tag, default_tag)) _run_cmd( ['docker', '-H=%s' % parsed.machine, 'tag', tag, default_tag]) # perform push (if needed) if parsed.push: if not parsed.loop: shell.include.devel.push.command(shell, args) else: msg = "Forbidden: You cannot push an image when using the experimental mode `--loop`." dtslogger.warn(msg) # perform remove (if needed) if parsed.rm: shell.include.devel.clean.command(shell, args)
def command(shell, args): prog = 'dts challenges evaluate' parser = argparse.ArgumentParser(prog=prog, usage=usage) group = parser.add_argument_group('Basic') group.add_argument('--no-cache', action='store_true', default=False, help="") group.add_argument('--no-build', action='store_true', default=False, help="") group.add_argument('--no-pull', action='store_true', default=False, help="") group.add_argument('--challenge', help="Specific challenge to evaluate") group.add_argument('--image', help="Evaluator image to run", default='duckietown/dt-challenges-evaluator:v4') group.add_argument('--shell', action='store_true', default=False, help="Runs a shell in the container") group.add_argument('--output', help="", default='output') group.add_argument('--visualize', help="Visualize the evaluation", action='store_true', default=False) parser.add_argument('--impersonate', type=str, default=None) group.add_argument('-C', dest='change', default=None) parsed = parser.parse_args(args) if parsed.change: os.chdir(parsed.change) client = check_docker_environment() command = ['dt-challenges-evaluate-local'] if parsed.no_cache: command.append('--no-cache') if parsed.no_build: command.append('--no-build') if parsed.challenge: command.extend(['--challenge', parsed.challenge]) if parsed.impersonate: command.extend(['--impersonate', parsed.impersonate]) output_rp = os.path.realpath(parsed.output) command.extend(['--output', parsed.output]) # # if parsed.features: # dtslogger.debug('Passing features %r' % parsed.features) # command += ['--features', parsed.features] # fake_dir = '/submission' tmpdir = '/tmp' UID = os.getuid() USERNAME = getpass.getuser() dir_home_guest = '/fake-home/%s' % USERNAME # os.path.expanduser('~') dir_fake_home_host = os.path.join(tmpdir, 'fake-%s-home' % USERNAME) if not os.path.exists(dir_fake_home_host): os.makedirs(dir_fake_home_host) dir_fake_home_guest = dir_home_guest dir_dtshell_host = os.path.join(os.path.expanduser('~'), '.dt-shell') dir_dtshell_guest = os.path.join(dir_fake_home_guest, '.dt-shell') dir_tmpdir_host = '/tmp' dir_tmpdir_guest = '/tmp' volumes = { '/var/run/docker.sock': { 'bind': '/var/run/docker.sock', 'mode': 'rw' } } d = os.path.join(os.getcwd(), parsed.output) if not os.path.exists(d): os.makedirs(d) volumes[output_rp] = {'bind': d, 'mode': 'rw'} volumes[os.getcwd()] = {'bind': os.getcwd(), 'mode': 'ro'} volumes[dir_tmpdir_host] = {'bind': dir_tmpdir_guest, 'mode': 'rw'} volumes[dir_dtshell_host] = {'bind': dir_dtshell_guest, 'mode': 'ro'} volumes[dir_fake_home_host] = { 'bind': dir_fake_home_guest, 'mode': 'rw' } volumes['/etc/group'] = {'bind': '/etc/group', 'mode': 'ro'} binds = [_['bind'] for _ in volumes.values()] for b1 in binds: for b2 in binds: if b1 == b2: continue if b1.startswith(b2): msg = 'Warning, it might be a problem to have binds with overlap' msg += '\n b1: %s' % b1 msg += '\n b2: %s' % b2 dtslogger.warn(msg) # command.extend(['-C', fake_dir]) env = {} extra_environment = dict(username=USERNAME, uid=UID, USER=USERNAME, HOME=dir_fake_home_guest) env.update(extra_environment) dtslogger.debug('Volumes:\n\n%s' % yaml.safe_dump(volumes, default_flow_style=False)) dtslogger.debug('Environment:\n\n%s' % yaml.safe_dump(env, default_flow_style=False)) from duckietown_challenges.rest import get_duckietown_server_url url = get_duckietown_server_url() dtslogger.info('The server URL is: %s' % url) if 'localhost' in url: h = socket.gethostname() replacement = h + '.local' dtslogger.warning( 'There is "localhost" inside, so I will try to change it to %r' % replacement) dtslogger.warning( 'This is because Docker cannot see the host as "localhost".') url = url.replace("localhost", replacement) dtslogger.warning('The new url is: %s' % url) dtslogger.warning( 'This will be passed to the evaluator in the Docker container.' ) env['DTSERVER'] = url container_name = 'local-evaluator' image = parsed.image name, tag = image.split(':') if not parsed.no_pull: dtslogger.info('Updating container %s' % image) dtslogger.info('This might take some time.') client.images.pull(name, tag) # try: container = client.containers.get(container_name) except: pass else: dtslogger.error('stopping previous %s' % container_name) container.stop() dtslogger.error('removing') container.remove() dtslogger.info('Starting container %s with %s' % (container_name, image)) detach = True env[DTShellConstants.DT1_TOKEN_CONFIG_KEY] = shell.get_dt1_token() dtslogger.info('Container command: %s' % " ".join(command)) # add all the groups on_mac = 'Darwin' in platform.system() if on_mac: group_add = [] else: group_add = [ g.gr_gid for g in grp.getgrall() if USERNAME in g.gr_mem ] interactive = False if parsed.shell: interactive = True detach = False command = ['/bin/bash', '-l'] params = dict(working_dir=os.getcwd(), user=UID, group_add=group_add, command=command, tty=interactive, volumes=volumes, environment=env, remove=True, network_mode='host', detach=detach, name=container_name) dtslogger.info('Parameters:\n%s' % json.dumps(params, indent=4)) client.containers.run(image, **params) if parsed.visualize: start_rqt_image_view() continuously_monitor(client, container_name)
def remove_container(container): try: container.remove() except Exception as e: dtslogger.warn("Container %s not found to remove! %s" % (container, e))
def stop_container(container): try: container.stop() except Exception as e: dtslogger.warn("Container %s not found to stop! %s" % (container, e))