# Buggy code
def extract_tarball(
    tarball_full_path, destination_directory=None, progress_update_callback=None
):
    if destination_directory is None:
        destination_directory = tarball_full_path[:-8]
    log.debug("extracting %s\n  to %s", tarball_full_path, destination_directory)

    assert not lexists(destination_directory), destination_directory

    with tarfile.open(tarball_full_path) as t:
        members = t.getmembers()
        num_members = len(members)

        def members_with_progress():
            for q, member in enumerate(members):
                if progress_update_callback:
                    progress_update_callback(q / num_members)
                yield member

        t.extractall(path=destination_directory, members=members_with_progress())

    if sys.platform.startswith("linux") and os.getuid() == 0:
        # When extracting as root, tarfile will by restore ownership
        # of extracted files.  However, we want root to be the owner
        # (our implementation of --no-same-owner).
        for root, dirs, files in os.walk(destination_directory):
            for fn in files:
                p = join(root, fn)
                os.lchown(p, 0, 0)


# Traceback (conda.CondaMultiError)
Traceback (most recent call last):
File "/Users/msarahan/miniconda3/bin/c3i", line 11, in <module>
load_entry_point('conda-concourse-ci', 'console_scripts', 'c3i')()
File "/Users/msarahan/code/conda-concourse-ci/conda_concourse_ci/cli.py", line 123, in main
execute.submit_one_off(**args.__dict__)
File "/Users/msarahan/code/conda-concourse-ci/conda_concourse_ci/execute.py", line 647, in submit_one_off
**kwargs)
File "/Users/msarahan/code/conda-concourse-ci/conda_concourse_ci/execute.py", line 508, in compute_builds
variant_config_files=kw.get('variant_config_files', []))
File "/Users/msarahan/code/conda-concourse-ci/conda_concourse_ci/execute.py", line 72, in collect_tasks
config=config)
File "/Users/msarahan/code/conda-concourse-ci/conda_concourse_ci/compute_build_graph.py", line 379, in construct_graph
recipes_dir, config=config)
File "/Users/msarahan/code/conda-concourse-ci/conda_concourse_ci/compute_build_graph.py", line 206, in add_recipe_to_graph
rendered = _get_or_render_metadata(recipe_dir, worker, config=config)
File "/Users/msarahan/miniconda3/lib/python3.6/site-packages/conda/utils.py", line 38, in __call__
return self.func(*args, **kw)
File "/Users/msarahan/code/conda-concourse-ci/conda_concourse_ci/compute_build_graph.py", line 199, in _get_or_render_metadata
bypass_env_check=True, config=config)
File "/Users/msarahan/code/conda-build/conda_build/api.py", line 49, in render
permit_undefined_jinja=not finalize):
File "/Users/msarahan/code/conda-build/conda_build/metadata.py", line 1781, in get_output_metadata_set
permit_unsatisfiable_variants=permit_unsatisfiable_variants)
File "/Users/msarahan/code/conda-build/conda_build/metadata.py", line 645, in finalize_outputs_pass
fm = finalize_metadata(om, permit_unsatisfiable_variants=permit_unsatisfiable_variants)
File "/Users/msarahan/code/conda-build/conda_build/render.py", line 387, in finalize_metadata
exclude_pattern)
File "/Users/msarahan/code/conda-build/conda_build/render.py", line 306, in add_upstream_pins
permit_unsatisfiable_variants, exclude_pattern)
File "/Users/msarahan/code/conda-build/conda_build/render.py", line 289, in _read_upstream_pin_files
extra_run_specs = get_upstream_pins(m, actions, env)
File "/Users/msarahan/code/conda-build/conda_build/render.py", line 251, in get_upstream_pins
pfe.execute()
File "/Users/msarahan/miniconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 494, in execute
self._execute_action(action)
File "/Users/msarahan/miniconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 515, in _execute_action
raise CondaMultiError(exceptions)
conda.CondaMultiError: OSError(62, 'Too many levels of symbolic links')
OSError(62, 'Too many levels of symbolic links')
OSError(62, 'Too many levels of symbolic links')

# Fixed code
def extract_tarball(
    tarball_full_path, destination_directory=None, progress_update_callback=None
):
    if destination_directory is None:
        destination_directory = tarball_full_path[:-8]
    log.debug("extracting %s\n  to %s", tarball_full_path, destination_directory)

    assert not lexists(destination_directory), destination_directory

    with tarfile.open(tarball_full_path) as t:
        members = t.getmembers()
        num_members = len(members)

        def members_with_progress():
            for q, member in enumerate(members):
                if progress_update_callback:
                    progress_update_callback(q / num_members)
                yield member

        try:
            t.extractall(path=destination_directory, members=members_with_progress())
        except EnvironmentError as e:
            if e.errno == ELOOP:
                raise CaseInsensitiveFileSystemError(
                    package_location=tarball_full_path,
                    extract_location=destination_directory,
                    caused_by=e,
                )
            else:
                raise

    if sys.platform.startswith("linux") and os.getuid() == 0:
        # When extracting as root, tarfile will by restore ownership
        # of extracted files.  However, we want root to be the owner
        # (our implementation of --no-same-owner).
        for root, dirs, files in os.walk(destination_directory):
            for fn in files:
                p = join(root, fn)
                os.lchown(p, 0, 0)