Closed software-testing-professional closed 2 years ago
I figured out that the problem is caused by apk
, which does not work correctly.
The motivation to use Tern as locally installed tool was some authentication issue with out private Docker registry.
The easiest solution for me was to switch to the Docker-based Tern, and provide a Docker config.json (/~.docker/config.json
) with the credentials stored.
So my problem is solved. :-)
Please reopen this issue.
I have the same issue. I need to have my own Dockerfile with Tern in it.
I tried it with Ubuntu 21.04 and 22.04. It seems to be always the same issue.
The output is:
# tern report -i golang:1.18-alpine
…
This report was generated by the Tern Project
Version: 2.10.0
Docker image: golang:1.18-alpine:
Layer 1:
info: Layer created by commands: /bin/sh -c #(nop) ADD file:5d673d25da3a14ce1f6cf66e4c7fd4f4b85a3759a9d93efb3fd9ff852b5b56e4 in /
info: Found 'Alpine Linux v3.15' in /etc/os-release.
info: Retrieved package metadata using apk default method.
error: chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
File licenses found in Layer: None
Packages found in Layer: None
=======================================================================================
Layer 2:
info: Layer created by commands: /bin/sh -c apk add --no-cache ca-certificates
info: Retrieved package metadata using apk default method.
error: chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
File licenses found in Layer: None
Packages found in Layer: None
=======================================================================================
Layer 3:
info: Layer created by commands: /bin/sh -c [ ! -e /etc/nsswitch.conf ] && echo 'hosts: files dns' > /etc/nsswitch.conf
warning:
Unrecognized Commands:[ ! -e /etc/nsswitch.conf ]
echo hosts: files dns > /etc/nsswitch.conf
info: Retrieved package metadata using apk default method.
error: chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
File licenses found in Layer: None
Packages found in Layer: None
=======================================================================================
Layer 4:
info: Layer created by commands: /bin/sh -c set -eux; apk add --no-cache --virtual .fetch-deps gnupg; arch="$(apk --print-arch)"; url=; case "$arch" in 'x86_64') export GOARCH='amd64' GOOS='linux'; ;; 'armhf') export GOARCH='arm' GOARM='6' GOOS='linux'; ;; 'armv7') export GOARCH='arm' GOARM='7' GOOS='linux'; ;; 'aarch64') export GOARCH='arm64' GOOS='linux'; ;; 'x86') export GO386='softfloat' GOARCH='386' GOOS='linux'; ;; 'ppc64le') export GOARCH='ppc64le' GOOS='linux'; ;; 's390x') export GOARCH='s390x' GOOS='linux'; ;; *) echo >&2 "error: unsupported architecture '$arch' (likely packaging update needed)"; exit 1 ;; esac; build=; if [ -z "$url" ]; then build=1; url='https://dl.google.com/go/go1.18.1.src.tar.gz'; sha256='efd43e0f1402e083b73a03d444b7b6576bb4c539ac46208b63a916b69aca4088'; fi; wget -O go.tgz.asc "$url.asc"; wget -O go.tgz "$url"; echo "$sha256 *go.tgz" | sha256sum -c -; GNUPGHOME="$(mktemp -d)"; export GNUPGHOME; gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 'EB4C 1BFD 4F04 2F6D DDCC EC91 7721 F63B D38B 4796'; gpg --batch --keyserver keyserver.ubuntu.com --recv-keys '2F52 8D36 D67B 69ED F998 D857 78BD 6547 3CB3 BD13'; gpg --batch --verify go.tgz.asc go.tgz; gpgconf --kill all; rm -rf "$GNUPGHOME" go.tgz.asc; tar -C /usr/local -xzf go.tgz; rm go.tgz; if [ -n "$build" ]; then apk add --no-cache --virtual .build-deps bash gcc go musl-dev ; ( cd /usr/local/go/src; export GOROOT_BOOTSTRAP="$(go env GOROOT)" GOHOSTOS="$GOOS" GOHOSTARCH="$GOARCH"; ./make.bash; ); apk del --no-network .build-deps; rm -rf /usr/local/go/pkg/*/cmd /usr/local/go/pkg/bootstrap /usr/local/go/pkg/obj /usr/local/go/pkg/tool/*/api /usr/local/go/pkg/tool/*/go_bootstrap /usr/local/go/src/cmd/dist/dist ; fi; apk del --no-network .fetch-deps; go version
warning:
Unrecognized Commands:set -eux
--print-arch
wget -O go.tgz.asc $url.asc
wget -O go.tgz $url
echo $sha256 *go.tgz | sha256sum -c -
-d
export GNUPGHOME
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys EB4C 1BFD 4F04 2F6D DDCC EC91 7721 F63B D38B 4796
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 2F52 8D36 D67B 69ED F998 D857 78BD 6547 3CB3 BD13
gpg --batch --verify go.tgz.asc go.tgz
gpgconf --kill all
rm -rf $GNUPGHOME go.tgz.asc
tar -C /usr/local -xzf go.tgz
rm go.tgz
go version
Non-deterministic branching statement:
case $arch in x86_64) export GOARCH=amd64 GOOS=linux
armhf) export GOARCH=arm GOARM=6 GOOS=linux
armv7) export GOARCH=arm GOARM=7 GOOS=linux
aarch64) export GOARCH=arm64 GOOS=linux
x86) export GO386=softfloat GOARCH=386 GOOS=linux
ppc64le) export GOARCH=ppc64le GOOS=linux
s390x) export GOARCH=s390x GOOS=linux
*) echo >&2 error: unsupported architecture '$arch' (likely packaging update needed
exit 1
esac
if [ -z $url ]
then build=1
url=https://dl.google.com/go/go1.18.1.src.tar.gz
sha256=efd43e0f1402e083b73a03d444b7b6576bb4c539ac46208b63a916b69aca4088
fi
if [ -n $build ]
then apk add --no-cache --virtual .build-deps bash gcc go musl-dev
cd /usr/local/go/src
export GOROOT_BOOTSTRAP=$(go env GOROOT) GOHOSTOS=$GOOS GOHOSTARCH=$GOARCH
./make.bash
apk del --no-network .build-deps
rm -rf /usr/local/go/pkg/*/cmd /usr/local/go/pkg/bootstrap /usr/local/go/pkg/obj /usr/local/go/pkg/tool/*/api /usr/local/go/pkg/tool/*/go_bootstrap /usr/local/go/src/cmd/dist/dist
fi
info: Retrieved package metadata using apk default method.
error: chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
File licenses found in Layer: None
Packages found in Layer: None
=======================================================================================
Layer 5:
info: Layer created by commands: /bin/sh -c mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
warning:
Unrecognized Commands:mkdir -p $GOPATH/src $GOPATH/bin
chmod -R 777 $GOPATH
info: Retrieved package metadata using apk default method.
error: chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
chroot: failed to run command ‘’: No such file or directory
File licenses found in Layer: None
Packages found in Layer: None
=======================================================================================
###########################################
# Summary of licenses found in Container: #
###########################################
None
2022-05-09 14:57:31,848 - DEBUG - rootfs - Running command: rm -rf /root/.tern/temp/mergedir
2022-05-09 14:57:32,082 - DEBUG - rootfs - Running command: rm -rf /root/.tern/temp/workdir
2022-05-09 14:57:32,084 - DEBUG - rootfs - Running command: rm -rf /root/.tern/temp/1/contents
2022-05-09 14:57:32,092 - DEBUG - rootfs - Running command: rm -rf /root/.tern/temp/2/contents
2022-05-09 14:57:32,100 - DEBUG - rootfs - Running command: rm -rf /root/.tern/temp/3/contents
2022-05-09 14:57:32,102 - DEBUG - rootfs - Running command: rm -rf /root/.tern/temp/4/contents
2022-05-09 14:57:32,292 - DEBUG - rootfs - Running command: rm -rf /root/.tern/temp/5/contents
2022-05-09 14:57:32,294 - DEBUG - prep - Tearing down...
2022-05-09 14:57:32,304 - DEBUG - __main__ - Finished
@Jeeppler can you provide a little more information about how you're running Tern when you see this error? How are you installing Tern and what version are you running? When you say "I need to have my own Dockerfile with Tern in it" -- what Dockerfile are you using? Also, did you try the workaround mentioned here?
@rnjudge thanks for opening the issue again. I installed Tern via pip
in a Ubuntu 22.04 container. Ubuntu 22.04 comes with Python 3.10 and Skopeo.
I need one more component in the Dockerfile, therefore I need to create my own Dockerfile. The workaround you mentioned does not work for me as I am not having issues with a private Docker registry. @software-testing-professional mentioned that apk
is the problem, that might be closer to the problem.
The part weird part is this:
chroot: failed to run command ‘’: No such file or directory
for whatever reason the command is empty. This only happens with Alpine images. Debian images can be scanned without any problems.
I will take a look at this today. When you say:
I need one more component in the Dockerfile, therefore I need to create my own Dockerfile.
can you share the Dockerfile you use to build Tern? and what is the "one more component" you are needing?
@rnjudge thanks for showing some interest in this issue. We want to integrate Tern into SecHub. As part of the integration we need to have our SecHub Product Delegation Service (PDS) component in the final Docker image. The PDS component ensures, that we run tools in a cluster, either on a VM or even in a Kubernetes cluster.
The current state of the Dockerfile is available here: https://github.com/mercedes-benz/sechub/blob/c36d1268ff4e3afeafe71af4693d8425ad8f1e3a/sechub-pds-solutions/tern/docker/Tern-Ubuntu.dockerfile. At the moment I simply build the Dockerfile and went into the container manually to test Tern. Simply running: tern report -i golang:1.18-alpine
.
@Jeeppler FYI, I am able to reproduce this issue and I'm looking at it. It does seem to be an apk specific issue unique to Ubuntu. When I use a debian based container I don't see this issue.
The find_shell()
function looks for the shell in the container being analyzed to run the commands needed to collect package metadata information. If it doesn't find one, it defaults to a blank string, which is what we are seeing in this particular issue.
When the failing chroot command is run, it should utilize the shell to run the apk commands as you can see in tern/utils/rootfs.py
below. Because the shell is defaulting to a blank string in the find_shell()
function, the command fails to run resulting in the "chroot: failed to run command" error.
result = root_command(chroot, target_dir, shell, '-c', command_string)
Below is a snippet where you can see that Tern is trying to find the shell that is symlinked pointing to the root of the container.
def find_shell(fspath):
"""Given the path to the filesystem where a shell may exist, find the
first available shell"""
for sh in command_lib.command_lib['common']['shells']:
realpath = os.path.realpath(os.path.join(fspath, sh[1:]))
# If realpath is a symlink and points to the root of the container,
# check for existence of the linked binary in current working dir
if realpath[0] == '/' and os.path.exists(os.path.join(fspath, realpath[1:])):
return sh
The behavior we're seeing happens because the realpath of the shell utility (i.e. /bin/sh) in a Ubuntu container chroot resolves to /usr/bin/busybox
when, in fact, the utility exists under /bin/busybox
.
>>> os.path.realpath(os.path.join(fspath, sh[1:]))
'/usr/bin/busybox'
root@5d8995710541:~/.tern/temp# tar -x -f /root/.tern/temp/df9b9388f04ad6279a7410b85cedfdcb2208c0a003da7ab5613af71079148139 -C /root/.tern/temp/mergedir
root@5d8995710541:~/.tern/temp# chroot /root/.tern/temp/mergedir
/ # ls -l /bin/sh
lrwxrwxrwx 1 root root 12 Apr 4 16:06 /bin/sh -> /bin/busybox
# ls -l /bin/busybox
-rwxr-xr-x 1 root root 824984 Apr 4 10:19 /bin/busybox
/ # ls -l /usr/bin/busybox
ls: /usr/bin/busybox: No such file or directory
In a Debian container, the same command resolves to /bin/busybox
where a shell can be found.
>>> os.path.realpath(os.path.join(fspath, sh[1:]))
'/bin/busybox'
I can insert a workaround for this to fix the chroot issue we are seeing.
@rnjudge thanks for analyzing the problem and finding the root cause.
@Jeeppler are you able to test the fix at all? I tested it myself bu would love a second set of eyes on it! I'm planning a patch release to include this fix as well.
@rnjudge yes, I can confirm, that I am now able to scan both golang:1.18-alpine
and alpine:latest
in a Ubuntu 22.04 container. Your fix works.
@rnjudge thanks for fixing the issue.
I'm running Tern in an Ubuntu 20.04 container, along with some other CycloneDX / BOM tools.
When I try to run a scan on an existing Docker image, these ERROR messages show up:
The installed Python is 3.8.10
Do you have any idea how I can fix this?
Best regards, Michael