# Buggy code
def extract_image(args):
    """The image can either be downloaded from a container registry or provided
    as an image tarball. Extract the image into a working directory accordingly
    Return an image name and tag and an image digest if it exists"""
    if args.docker_image:
        # extract the docker image
        image_attrs = docker_api.dump_docker_image(args.docker_image)
        if image_attrs:
            if image_attrs["RepoTags"]:
                image_string = image_attrs["RepoTags"][0]
            if image_attrs["RepoDigests"]:
                image_digest = image_attrs["RepoDigests"][0]
            return image_string, image_digest
        logger.critical("Cannot extract Docker image")
    if args.raw_image:
        # for now we assume that the raw image tarball is always
        # the product of "docker save", hence it will be in
        # the docker style layout
        if rootfs.extract_tarfile(args.raw_image, rootfs.get_working_dir()):
            return args.raw_image, None
        logger.critical("Cannot extract raw image")
    return None, None


# Traceback (subprocess.CalledProcessError)
tevoinea@tevoinea-Virtual-Machine:~/tern$ docker run --privileged --device /dev/fuse -v /var/run/docker.sock:/var/run/docker.sock --rm ternd report -f json -i ubuntu@sha256:2b90cad5ded7946db07a28252618b9c8b7f4f103fc39266bcc795719d1362d40 > output.json
2020-09-03 21:00:57,783 - DEBUG - __main__ - Starting...
2020-09-03 21:00:57,784 - DEBUG - run - Setting up...
2020-09-03 21:00:57,799 - DEBUG - container - Checking if image "ubuntu@sha256:2b90cad5ded7946db07a28252618b9c8b7f4f103fc39266bcc795719d1362d40" is available on disk...
2020-09-03 21:00:57,803 - DEBUG - container - Image "ubuntu@sha256:2b90cad5ded7946db07a28252618b9c8b7f4f103fc39266bcc795719d1362d40" found
2020-09-03 21:00:58,917 - DEBUG - rootfs - Running command: tar -tf /root/.tern/temp.tar
2020-09-03 21:00:58,962 - DEBUG - rootfs - Running command: tar -x --exclude=.wh.* -f /root/.tern/temp.tar -C /root/.tern/temp
2020-09-03 21:00:59,086 - DEBUG - rootfs - Running command: tar -tf /root/.tern/temp/9db0dcee2c01ab15b8419093c4fcfc585e3a37f0b4b63dda83c96c465f6f6521/layer.tar
2020-09-03 21:00:59,099 - DEBUG - rootfs - Running command: tar -x --exclude=.wh.* -f /root/.tern/temp/9db0dcee2c01ab15b8419093c4fcfc585e3a37f0b4b63dda83c96c465f6f6521/layer.tar -C /root/.tern/temp/9db0dcee2c01ab15b8419093c4fcfc585e3a37f0b4b63dda83c96c465f6f6521/contents
2020-09-03 21:00:59,246 - DEBUG - rootfs - Running command: chmod +x /usr/local/lib/python3.7/dist-packages/tern/tools/fs_hash.sh
2020-09-03 21:00:59,610 - DEBUG - rootfs - Running command: /usr/local/lib/python3.7/dist-packages/tern/tools/fs_hash.sh /root/.tern/temp/9db0dcee2c01ab15b8419093c4fcfc585e3a37f0b4b63dda83c96c465f6f6521/contents
2020-09-03 21:01:07,677 - DEBUG - rootfs - Running command: tar -tf /root/.tern/temp/49c388ec605a3411c4d5b412e6fb46e734fe3f2c6006dda31983f58aafe05146/layer.tar
2020-09-03 21:01:07,686 - DEBUG - rootfs - Running command: tar -x --exclude=.wh.* -f /root/.tern/temp/49c388ec605a3411c4d5b412e6fb46e734fe3f2c6006dda31983f58aafe05146/layer.tar -C /root/.tern/temp/49c388ec605a3411c4d5b412e6fb46e734fe3f2c6006dda31983f58aafe05146/contents
2020-09-03 21:01:07,698 - DEBUG - rootfs - Running command: chmod +x /usr/local/lib/python3.7/dist-packages/tern/tools/fs_hash.sh
2020-09-03 21:01:07,702 - DEBUG - rootfs - Running command: /usr/local/lib/python3.7/dist-packages/tern/tools/fs_hash.sh /root/.tern/temp/49c388ec605a3411c4d5b412e6fb46e734fe3f2c6006dda31983f58aafe05146/contents
2020-09-03 21:01:07,728 - DEBUG - rootfs - Running command: tar -tf /root/.tern/temp/e44e131d684525597610af42c8db14102ad22ba156ad6ec3f5df068cea515759/layer.tar
2020-09-03 21:01:07,732 - DEBUG - rootfs - Running command: tar -x --exclude=.wh.* -f /root/.tern/temp/e44e131d684525597610af42c8db14102ad22ba156ad6ec3f5df068cea515759/layer.tar -C /root/.tern/temp/e44e131d684525597610af42c8db14102ad22ba156ad6ec3f5df068cea515759/contents
2020-09-03 21:01:07,738 - DEBUG - rootfs - Running command: chmod +x /usr/local/lib/python3.7/dist-packages/tern/tools/fs_hash.sh
2020-09-03 21:01:07,741 - DEBUG - rootfs - Running command: /usr/local/lib/python3.7/dist-packages/tern/tools/fs_hash.sh /root/.tern/temp/e44e131d684525597610af42c8db14102ad22ba156ad6ec3f5df068cea515759/contents
2020-09-03 21:01:07,766 - DEBUG - rootfs - Running command: tar -tf /root/.tern/temp/3d3abe9e801a99cc9ca3bb08981d58ccfab161d9b1ba8bcf79cce51c7baf9787/layer.tar
2020-09-03 21:01:07,769 - DEBUG - rootfs - Running command: tar -x --exclude=.wh.* -f /root/.tern/temp/3d3abe9e801a99cc9ca3bb08981d58ccfab161d9b1ba8bcf79cce51c7baf9787/layer.tar -C /root/.tern/temp/3d3abe9e801a99cc9ca3bb08981d58ccfab161d9b1ba8bcf79cce51c7baf9787/contents
2020-09-03 21:01:07,772 - DEBUG - rootfs - Running command: chmod +x /usr/local/lib/python3.7/dist-packages/tern/tools/fs_hash.sh
2020-09-03 21:01:07,776 - DEBUG - rootfs - Running command: /usr/local/lib/python3.7/dist-packages/tern/tools/fs_hash.sh /root/.tern/temp/3d3abe9e801a99cc9ca3bb08981d58ccfab161d9b1ba8bcf79cce51c7baf9787/contents
2020-09-03 21:01:07,789 - DEBUG - common - Reading files in filesystem...
2020-09-03 21:01:08,317 - DEBUG - rootfs - Running command: mount -o bind /root/.tern/temp/9db0dcee2c01ab15b8419093c4fcfc585e3a37f0b4b63dda83c96c465f6f6521/contents /root/.tern/temp/mergedir
2020-09-03 21:01:08,326 - DEBUG - rootfs - Running command: mount -t proc /proc /root/.tern/temp/mergedir/proc
2020-09-03 21:01:08,332 - DEBUG - rootfs - Running command: mount -o bind /sys /root/.tern/temp/mergedir/sys
2020-09-03 21:01:08,335 - DEBUG - rootfs - Running command: mount -o bind /dev /root/.tern/temp/mergedir/dev
2020-09-03 21:01:08,342 - DEBUG - rootfs - Running command: cp /etc/resolv.conf /root/.tern/temp/mergedir/etc/resolv.conf
2020-09-03 21:01:08,348 - DEBUG - rootfs - Running command: unshare -pf --mount-proc=/root/.tern/temp/mergedir/proc chroot /root/.tern/temp/mergedir /bin/sh -c dpkg --get-selections | cut -f1 -d':' | awk '{print $1}'
2020-09-03 21:01:08,364 - ERROR - rootfs - Command failed. chroot: failed to run command ‘/bin/sh’: Exec format error

2020-09-03 21:01:08,364 - WARNING - rootfs - Error executing command in chroot
2020-09-03 21:01:08,365 - DEBUG - rootfs - Running command: umount /root/.tern/temp/mergedir/proc
2020-09-03 21:01:08,371 - DEBUG - rootfs - Running command: umount /root/.tern/temp/mergedir/sys
2020-09-03 21:01:08,374 - DEBUG - rootfs - Running command: umount /root/.tern/temp/mergedir/dev
2020-09-03 21:01:08,376 - DEBUG - rootfs - Running command: umount -rl /root/.tern/temp/mergedir
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/tern/utils/rootfs.py", line 237, in run_chroot_command
shell, '-c', command_string)
File "/usr/local/lib/python3.7/dist-packages/tern/utils/rootfs.py", line 77, in root_command
1, cmd=full_cmd, output=None, stderr=error.decode())
subprocess.CalledProcessError: Command '['unshare', '-pf', '--mount-proc=/root/.tern/temp/mergedir/proc', 'chroot', '/root/.tern/temp/mergedir', '/bin/sh', '-c', "dpkg --get-selections | cut -f1 -d':' | awk '{print $1}'"]' returned non-zero exit status 1.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/bin/tern", line 8, in <module>
sys.exit(main())
File "/usr/local/lib/python3.7/dist-packages/tern/__main__.py", line 204, in main
do_main(args)
File "/usr/local/lib/python3.7/dist-packages/tern/__main__.py", line 105, in do_main
run.execute_docker_image(args)
File "/usr/local/lib/python3.7/dist-packages/tern/analyze/docker/run.py", line 91, in execute_docker_image
analyze(full_image, args)
File "/usr/local/lib/python3.7/dist-packages/tern/analyze/docker/run.py", line 70, in analyze
args.driver)
File "/usr/local/lib/python3.7/dist-packages/tern/analyze/docker/analyze.py", line 40, in analyze_docker_image
shell = analyze_first_layer(image_obj, master_list, redo)
File "/usr/local/lib/python3.7/dist-packages/tern/analyze/docker/analyze.py", line 90, in analyze_first_layer
execute_base_layer(image_obj.layers[0], binary, shell)
File "/usr/local/lib/python3.7/dist-packages/tern/analyze/docker/analyze.py", line 102, in execute_base_layer
common.add_base_packages(base_layer, binary, shell)
File "/usr/local/lib/python3.7/dist-packages/tern/analyze/common.py", line 341, in add_base_packages
work_dir, envs)
File "/usr/local/lib/python3.7/dist-packages/tern/analyze/common.py", line 239, in collate_list_metadata
work_dir, envs)
File "/usr/local/lib/python3.7/dist-packages/tern/command_lib/command_lib.py", line 240, in get_pkg_attr_list
snippet_list, shell, package=package_name)
File "/usr/local/lib/python3.7/dist-packages/tern/command_lib/command_lib.py", line 197, in invoke_in_rootfs
result = rootfs.run_chroot_command(full_cmd, shell)
File "/usr/local/lib/python3.7/dist-packages/tern/utils/rootfs.py", line 242, in run_chroot_command
1, cmd=command_string, output=error.output.decode('utf-8'))
AttributeError: 'NoneType' object has no attribute 'decode'

# Fixed code
def extract_image(args):
    """The image can either be downloaded from a container registry or provided
    as an image tarball. Extract the image into a working directory accordingly
    Return an image name and tag and an image digest if it exists"""
    if args.docker_image:
        # extract the docker image
        image_attrs = docker_api.dump_docker_image(args.docker_image)
        if image_attrs:
            # repo name and digest is preferred, but if that doesn't exist
            # the repo name and tag will do
            if image_attrs["RepoDigests"]:
                image_string = image_attrs["RepoDigests"][0]
            if image_attrs["RepoTags"]:
                image_string = image_attrs["RepoTags"][0]
            return image_string
        logger.critical("Cannot extract Docker image")
    if args.raw_image:
        # for now we assume that the raw image tarball is always
        # the product of "docker save", hence it will be in
        # the docker style layout
        if rootfs.extract_tarfile(args.raw_image, rootfs.get_working_dir()):
            return args.raw_image
        logger.critical("Cannot extract raw image")
    return None