def run_app(self):
     """Runs desired binary and returns the time elapsed during execution."""
     cmd = self.gen_command()
     start_time = time.time()
     run_command(cmd)
     end_time = time.time()
     return end_time - start_time
示例#2
0
    def s3_cp(self,
              src,
              dst,
              exclude=None,
              include=None,
              recursive=True,
              run_silently=False):
        """Copies files in src to dst according to given exclude and include filters

        Args:
            src (str): source path
            dst (str): destination path
            exclude (str): exclude filter
            include (str): include filter
        """
        try:
            filters = ""
            if exclude:
                filters += f" --exclude '{exclude}'"
            if include:
                filters += f" --include '{include}'"
            if recursive:
                filters += f" --recursive"
            run_command(f"aws s3 cp {src} {dst} {filters}", run_silently)
        except subprocess.CalledProcessError:
            raise Exception(f"Failed to cp {src} to {dst}!")
示例#3
0
def upload(src, dst, filters=None, run_silently=False):
    """Recursively uploads the objects from source that adhere to the filters. No
    operation is performed for local paths.

    Args:
        src (str): Path to the source directory.
        dst (str): Path to the destination directory where uploaded files will be saved.
        filters (list[str], optional): List of filters to choose files to upload.
        run_silently (bool, optional): Whether or not to display results to stdout.

    Returns:
        bool: Success of upload.
    """
    filters = filters if filters is not None else []
    remote = Address(dst)

    if remote.protocol == "s3":
        print("Uploading to S3...")

        # Slight difference between downloading a single file and a folder
        if "." in os.path.basename(remote.path):
            upload_cmd = f"aws s3 cp {src} {dst}"
        else:
            filter_cmd = "--exclude '*' "
            filter_cmd += " ".join(
                [f"--include '{filter}'" for filter in filters])
            upload_cmd = f"aws s3 sync {src} {dst} {filter_cmd}"
        run_command(upload_cmd, run_silently)
        return True
    return False
示例#4
0
def main(argv):
    """Creates a kops cluster, deploys a kubernetes cluster atop it, and runs render
    with the kubernetes nodes as workers. The cluster remain upon completion and must
    be externally terminated (re: clean.py).

    Args:
        argv (list[str]): List of arguments (used interally by abseil).
    """
    aws_util = AWSUtil(FLAGS.csv_path, region_name=FLAGS.region)
    key_fn = create_key(aws_util)

    instance_id, ip_staging = create_instance(aws_util, key_fn)
    ec2_file = os.path.expanduser(FLAGS.ec2_file)
    with open(ec2_file, "w") as f:
        f.write(instance_id)

    configure_remote_shell(aws_util, key_fn, ip_staging)

    master_ip = run_ssh_command(
        key_fn,
        ip_staging,
        """aws ec2 describe-instances \
                    --instance-ids $(ec2metadata --instance-id) \
                    --query 'Reservations[*].Instances[*].PublicIpAddress' \
                    --output text""",
        hide=True,
    )

    ecr_registry_name = f"fb360-{aws_util.username}"
    repo_uri = get_repo_uri(key_fn, ip_staging, ecr_registry_name)
    if not repo_uri.strip():
        run_ssh_command(
            key_fn,
            ip_staging,
            f"aws ecr create-repository --repository-name {ecr_registry_name}",
        )
        repo_uri = get_repo_uri(key_fn, ip_staging, ecr_registry_name)

    render_pid = get_render_pid(key_fn, ip_staging)
    if render_pid is None:
        setup_instance(aws_util, key_fn, ip_staging, master_ip, repo_uri)
        run_render(key_fn, ip_staging, master_ip)
        render_pid = get_render_pid(key_fn, ip_staging)

    sync_logs = f"""while true; do \
        rsync -avz -e 'ssh -i {key_fn}' \
        ubuntu@{ip_staging}:/home/ubuntu/logs/ {config.DOCKER_INPUT_ROOT}/logs/; \
        sleep 10; \
    done &"""
    run_command(sync_logs, run_async=True)

    display_render_progress = f"""tail --pid {render_pid} -n +1 -f render.out"""
    run_ssh_command(key_fn, ip_staging, display_render_progress)
示例#5
0
    def on_process_finished(self, exitCode, exitStatus, p_id):
        """Callback event handler for a process completing.

        Args:
            exitCode (int): Return code from running the process.
            exitStatus (str): Description message of process exit.
            p_id (str): PID of completed process.
        """
        if self.parent.is_aws:
            remote_rigs = os.path.join(self.parent.ui_flags.project_root,
                                       "rigs/")
            run_command(f"aws s3 sync {self.path_rigs} {remote_rigs}")
        common.on_process_finished(self, p_id)
示例#6
0
def setup_local_gpu():
    # Check if we are using Linux and we have an NVIDIA card, and we are not rendering in AWS
    if not FLAGS.project_root.startswith("s3://"):
        host_os = get_os_type(config.LOCALHOST)
        if host_os == OSType.LINUX and pyvidia.get_nvidia_device() is not None:
            gpu_script = os.path.join(dir_scripts, "render", "setup_gpu.sh")
            print(glog.green("Setting up GPU environment..."))
            run_command(f"/bin/bash {gpu_script}",
                        run_silently=not FLAGS.verbose)
        else:
            print(
                glog.yellow(
                    "We can only access an Nvidia GPU from a Linux host. Skipping Docker GPU setup"
                ))
示例#7
0
def get_sample_file(src, run_silently=False):
    """Gets the name of a single objects in the source directory. Local paths are
    also supported.

    Args:
        src (str): Path to the source directory.
        run_silently (bool, optional): Whether or not to display results to stdout.

    Returns:
        str: Single filename from the directory. If no such file or directory exists,
            None is returned instead.
    """
    remote = Address(src)

    if remote.protocol == "s3":
        if not src.endswith("/"):
            src = src + "/"
        raw_output = run_command(f"aws s3 ls {src}", run_silently)
        raw_lines = raw_output.split("\n")
        if len(raw_lines) > 0:
            return raw_lines[0].split(" ")[-1]
        return None
    else:
        for root, _, files in os.walk(src):
            for file in files:
                if not file.startswith("."):
                    return os.path.join(root, file)
        return None
    def run_app(self, binary_name, args=None, log_file=None):
        """Runs desired binary with arguments pulled from the corresponding flagfile if
        None are passed in.

        Args:
            binary_name (str): Name of the binary.
            args (str, optional): CLI arguments. If None is passed in, this is pulled from
                the corresponding flagfile from res/test/.
            stream (bool, optional): Whether or not to stream output to the screen.
        """
        if args is None:
            cmd = self.gen_command_flagfile(binary_name)
        else:
            cmd = self.gen_command(binary_name, args, self.io_args.output_root,
                                   self.io_args.log_dir)
        run_command(cmd, file_fn=log_file)
示例#9
0
    def s3_sync(self, src, dst, exclude=None, include=None, run_silently=False):
        """Syncs files in src to dst according to given exclude and include filters

        Args:
            src (str): source path
            dst (str): destination path
            exclude (str): exclude filter
            include (list[str]): include filters
        """
        try:
            filters = ""
            if exclude:
                filters += f" --exclude '{exclude}'"
            if include:
                for incl in include:
                    filters += f" --include '{incl}'"
            run_command(f"aws s3 sync {src} {dst} {filters}", run_silently)
        except subprocess.CalledProcessError:
            raise Exception(f"Failed to sync {src} to {dst}!")
示例#10
0
def _run_bin(msg):
    """Runs the binary associated with the message. The execution assumes the worker is
    running in a configured Docker container.

    Args:
        msg (dict[str, str]): Message received from RabbitMQ publisher.
    """
    msg_cp = copy(msg)

    # The binary flag convention includes the "last" frame
    msg_cp["last"] = get_frame_name(int(msg["last"]))
    app_name = msg_cp["app"].split(":")[0]
    relevant_flags = [flag["name"] for flag in bin_to_flags[app_name]]
    cmd_flags = " ".join([
        f"--{flag}={msg_cp[flag]}" for flag in relevant_flags
        if flag in msg_cp and msg_cp[flag] != ""
    ])

    # Order is determined to prevent substrings from being accidentally replaced
    input_root = msg_cp["input_root"].rstrip("/")
    output_root = msg_cp["output_root"].rstrip("/")

    root_order = ([output_root, input_root]
                  if input_root in output_root else [input_root, output_root])
    root_to_docker = {
        input_root: config.DOCKER_INPUT_ROOT,
        output_root: config.DOCKER_OUTPUT_ROOT,
    }

    for root in root_order:
        if not os.path.exists(root):
            cmd_flags = cmd_flags.replace(root, root_to_docker[root])

    bin_path = os.path.join(config.DOCKER_BUILD_ROOT, "bin", app_name + ".exe")
    cmd = f"set GLOG_alsologtostderr=1 && set GLOG_stderrthreshold=0 && {bin_path} {cmd_flags}"
    run_command(cmd)
示例#11
0
    def s3_ls(self, s3_url, run_silently=False):
        """Lists the contents of the given S3 path

        Args:
            s3_url (str): S3 URL
        """
        if not s3_url.endswith("/"):
            s3_url = f"{s3_url}/"
        try:
            raw_output = run_command(f"aws s3 ls {s3_url}", run_silently)
        except subprocess.CalledProcessError:
            if not run_silently:
                print(f"Failed to list: {s3_url}!")
            return []

        raw_lines = raw_output.split("\n")
        return [raw_line.split(" ")[-1].strip().rstrip("/") for raw_line in raw_lines]
示例#12
0
 def configure_shell(self, run_silently=False):
     """Configures local shell with the AWS credentials and region."""
     cmd = "aws configure set"
     run_command(
         f"{cmd} aws_access_key_id {self.aws_access_key_id}",
         run_silently=run_silently,
     )
     run_command(
         f"{cmd} aws_secret_access_key {self.aws_secret_access_key}",
         run_silently=run_silently,
     )
     if self.region_name:
         run_command(f"{cmd} default.region {self.region_name}",
                     run_silently=run_silently)
示例#13
0
def copy_frame(src,
               dst,
               frame,
               cameras,
               run_silently=False,
               uncompressed=False):
    """Copies a single frame to a new directory. A standard cp operation is
    performed for local paths.

    Args:
        src (str): Path to the source directory.
        dst (str): Path to the destination directory.
        frames (list[str]): Frame names being copied.
        run_silently (bool, optional): Whether or not to display results to stdout.
        uncompressed (bool, optional): Whether or not the src should be uncompressed before
            copying to the destination. Only relevant for archived intermediates.
    """
    remote = Address(src)
    if remote.protocol == "s3":
        frame_tar_fn = f"{frame}.tar"
        src_frame = os.path.join(src, frame_tar_fn)
        if uncompressed:
            tmp_extract_dir = "tmp"
            run_command(f"aws s3 cp {src_frame} .", run_silently)

            os.makedirs(tmp_extract_dir, exist_ok=True)
            tar_ref = tarfile.open(frame_tar_fn)
            tar_ref.extractall(tmp_extract_dir)
            tar_ref.close()

            run_command(f"aws s3 cp {tmp_extract_dir} {dst} --recursive",
                        run_silently)
            rmtree(tmp_extract_dir)
            os.remove(frame_tar_fn)
        else:
            dst_frame = os.path.join(dst, frame_tar_fn)
            run_command(f"aws s3 cp {src_frame} {dst_frame}", run_silently)
    else:
        for camera in cameras:
            src_cam = os.path.join(src, camera)
            dst_cam = os.path.join(dst, camera)
            os.makedirs(dst_cam, exist_ok=True)

            # Copy all extensions for current frame
            for f in glob.iglob(f"{src_cam}/{frame}.*", recursive=False):
                f = os.path.basename(f)
                copyfile(os.path.join(src_cam, f), os.path.join(dst_cam, f))
示例#14
0
def setup_master(base_params):
    """Sets up the master node for rendering.

    Args:
        base_params (dict[str, _]): Map of all the FLAGS defined in render.py.
    """
    protocol = Address(base_params["input_root"]).protocol
    try:
        if protocol == "s3":
            run_command("sudo service rabbitmq-server start")
        else:
            run_command("service rabbitmq-server start")
    except Exception:
        runtime = "nvidia" if which("nvidia-docker") else ""
        cmd = f"""docker run --runtime={runtime} -p 5672:5672 -p 15672:15672 \
            -d {config.DOCKER_IMAGE}:latest rabbitmq-server start"""
        run_command(cmd)
示例#15
0
def listdir(src, run_silently=False, recursive=True):
    """Lists objects in a source directory. A standard ls is performed for local paths.

    Args:
        src (str): Path to the source directory.
        run_silently (bool, optional): Whether or not to display results to stdout.

    Returns:
        set[str]: Set of contained filenames.
    """
    remote = Address(src)

    if remote.protocol == "s3":
        if not src.endswith("/"):
            src = src + "/"
        try:
            cmd = f"aws s3 ls {src}"
            if recursive:
                cmd = cmd + "--recursive"
            raw_output = run_command(cmd, run_silently)
        except Exception:
            return set(
            )  # An exception is raised if no such src directory is found
        raw_lines = raw_output.split("\n")
        files = {raw_line.split(" ")[-1] for raw_line in raw_lines}
        return set(filter(None, files))  # Remove empty results
    else:
        result = set()
        if recursive:
            for root, _, files in os.walk(src):
                for file in files:
                    if not file.startswith("."):
                        result.add(
                            os.path.join(os.path.relpath(root, src), file))
        else:
            result = set(os.listdir(src))
        return result
示例#16
0
def run_ui(client, docker_img):
    """Starts the UI.

    Args:
        client (DockerClient): Docker client configured to the host environment.
        docker_img (str): Name of the Docker image.
    """
    if not FLAGS.verbose:
        print(glog.green("Initializing container"), end="")
        loading_context = RepeatedTimer(1,
                                        lambda: print(glog.green("."), end=""))

    host_os = get_os_type(config.LOCALHOST)

    # Setup steps for X11 forwarding vary slightly per the host operating system
    volumes = {
        "/var/run/docker.sock": {
            "bind": "/var/run/docker.sock",
            "mode": "ro"
        }
    }
    if host_os == OSType.MAC or host_os == OSType.LINUX:
        volumes.update(
            {"/tmp/.X11-unix": {
                "bind": "/tmp/.X11-unix",
                "mode": "ro"
            }})

    if host_os == OSType.MAC or host_os == OSType.LINUX:
        run_command(f"xhost + {config.LOCALHOST}",
                    run_silently=not FLAGS.verbose)
    if host_os == OSType.LINUX:
        run_command(f"xhost + {config.DOCKER_LOCAL_HOSTNAME}",
                    run_silently=not FLAGS.verbose)

    host_to_docker_path = {FLAGS.project_root: config.DOCKER_INPUT_ROOT}

    project = Project(
        FLAGS.project_root,
        FLAGS.cache,
        FLAGS.csv_path,
        FLAGS.s3_sample_frame,
        FLAGS.s3_ignore_fullsize_color,
        FLAGS.verbose,
    )
    project.verify()

    cmds = [
        "cd scripts/ui",
        f"""python3 -u dep.py \
        --host_os={get_os_type(config.LOCALHOST)} \
        --local_bin={FLAGS.local_bin} \
        --master={FLAGS.master} \
        --password={FLAGS.password} \
        --project_root={FLAGS.project_root} \
        --s3_ignore_fullsize_color={FLAGS.s3_ignore_fullsize_color} \
        --s3_sample_frame={FLAGS.s3_sample_frame} \
        --username={FLAGS.username} \
        --verbose={FLAGS.verbose}""",
    ]

    docker_networks = client.networks.list()
    network_names = [docker_network.name for docker_network in docker_networks]
    if config.DOCKER_NETWORK not in network_names:
        client.networks.create(config.DOCKER_NETWORK, driver="bridge")

    project_address = Address(FLAGS.project_root)
    project_protocol = project_address.protocol
    if project_protocol == "smb":
        mounts = docker_mounts(FLAGS.project_root, host_to_docker_path,
                               FLAGS.username, FLAGS.password)
        cmds = [f"mkdir {config.DOCKER_INPUT_ROOT}"] + mounts + cmds

        local_project_root = None
    elif project_protocol == "s3":
        glog.check_ne(FLAGS.csv_path, "",
                      "csv_path cannot be empty if rendering on AWS")
        aws_util = AWSUtil(FLAGS.csv_path, s3_url=FLAGS.project_root)
        glog.check(
            aws_util.s3_bucket_is_valid(FLAGS.project_root),
            f"Invalid S3 project path: {FLAGS.project_root}",
        )

        volumes.update({
            FLAGS.csv_path: {
                "bind": config.DOCKER_AWS_CREDENTIALS,
                "mode": "rw"
            }
        })

        project_name = project_address.path
        cache_path = os.path.join(os.path.expanduser(FLAGS.cache),
                                  project_name)
        os.makedirs(cache_path, exist_ok=True)
        volumes.update(
            {cache_path: {
                "bind": config.DOCKER_INPUT_ROOT,
                "mode": "rw"
            }})

        local_project_root = cache_path
    else:
        glog.check(
            os.path.isdir(FLAGS.project_root),
            f"Invalid project path: {FLAGS.project_root}",
        )
        volumes.update({
            host_path: {
                "bind": docker_path,
                "mode": "rw"
            }
            for host_path, docker_path in host_to_docker_path.items()
        })
        local_project_root = FLAGS.project_root

    ipc_dir = os.path.join(local_project_root, "ipc")
    os.makedirs(ipc_dir, exist_ok=True)
    volumes.update({ipc_dir: {"bind": config.DOCKER_IPC_ROOT, "mode": "rw"}})

    cmd = f'/bin/bash -c "{" && ".join(cmds)}"'
    global container_name
    display = ":0" if host_os == OSType.LINUX else "host.docker.internal:0"
    runtime = "nvidia" if which("nvidia-docker") else ""
    if host_os != OSType.LINUX:
        display = "host.docker.internal:0"

    if not FLAGS.verbose:
        loading_context.stop()
        print("")

    try:
        container = client.containers.run(
            docker_img,
            command=cmd,
            detach=True,
            environment={"DISPLAY": display},
            runtime=runtime,
            network=config.DOCKER_NETWORK,
            ports={
                config.RABBITMQ_PORT: config.RABBITMQ_PORT,
                config.RABBITMQ_MANAGE_PORT: config.RABBITMQ_MANAGE_PORT,
            },
            privileged=True,
            volumes=volumes,
            stderr=True,
        )
    except docker.errors.APIError as e:
        if "port is already allocated" in str(e):
            raise Exception(
                "Failed to launch UI! Ensure: \n"
                "(1) No other instance of UI is running (check: docker ps) and\n"
                "(2) RabbitMQ is not running on your machine (check: ps aux | grep 'rabbitmq')"
            ) from None
        raise e
    container_name = container.name
    create_viewer_watchdog(client, ipc_dir, local_project_root)
示例#17
0
    def on_modified(self, event):
        """When a viewer file is modified from the UI, the appropriate viewer runs on the host.

        Args:
            event (watchdog.FileSystemEvent): Watchdog event for when viewer file has been modified.
        """
        if isinstance(event, DirModifiedEvent):
            return

        ipc_name = os.path.basename(event.src_path)
        host_os = get_os_type(config.LOCALHOST)
        if ipc_name == config.DOCKER_RIFT_VIEWER_IPC and host_os != OSType.WINDOWS:
            print(glog.yellow("RiftViewer is only supported on Windows!"))
            return

        app_name = config.get_app_name(ipc_name)
        if not app_name:
            print(glog.red(f"Invalid IPC name: {ipc_name}"))
            return

        try:
            output_dir = posixpath.join(self.local_project_root,
                                        config.OUTPUT_ROOT_NAME)
            if ipc_name == config.DOCKER_RIFT_VIEWER_IPC:
                fused_dir = posixpath.join(output_dir,
                                           image_type_paths["fused"])
                fused_json = self.get_fused_json(fused_dir)
                if not fused_json:
                    print(
                        glog.red(f"Cannot find fused rig json in {fused_dir}"))
                    return
                cmd_flags = f"""--rig={posixpath.join(fused_dir, fused_json)} \
                    --catalog={posixpath.join(fused_dir, "fused.json")} \
                    --strip_files={posixpath.join(fused_dir, "fused_0.bin")}"""
            elif ipc_name in [
                    config.DOCKER_SMR_IPC, config.DOCKER_SMR_ONSCREEN_IPC
            ]:
                flags_render = self.get_render_flags("export")

                if ipc_name == config.DOCKER_SMR_IPC:
                    flags_render["output"] = posixpath.join(
                        output_dir, image_type_paths["exports"])
                flags_smr = [flag["name"] for flag in bin_to_flags[app_name]]

                cmd_flags = ""
                ignore_onscreen = ["format", "output"]
                for flag in flags_render:
                    if flag in flags_smr:
                        if (flag in ignore_onscreen and ipc_name
                                == config.DOCKER_SMR_ONSCREEN_IPC):
                            continue
                        cmd_flags += f" --{flag}={flags_render[flag]}"
                cmd_flags = cmd_flags.replace(config.DOCKER_INPUT_ROOT,
                                              self.local_project_root)

            cmd = f"{posixpath.join(FLAGS.local_bin, app_name)} {cmd_flags}"
            if os.name != "nt":  # GLOG initiatives don't work in Powershell/cmd
                cmd = f"GLOG_alsologtostderr=1 GLOG_stderrthreshold=0 {cmd}"
            run_command(cmd)
        except Exception as e:
            print(glog.red(e))