Inside Docker tar extract failed ,If use the option "-O"

Build it from Docker 1.10 from Centos 7.

I am currently revamp our old project as a Docker Container.

In which i stuck at the stage where in the “entrypoint” i call a bash script , which in turn extract the some tgz inside docker.

Here is the following unzip they used:

tar -zxOf /tmp/FILENAME.tgz FILENAME.tgz | tar -zxf - somefiles.txt 1>/dev/null 2>&1

tar: FILENAME.gz: Not found in archive
tar: Exiting with failure status due to previous errors

and its is failed inside the docker

Instead of docker , if we ran this command in host machine it will works.

All they do in the script extract some file from archive for verification.

Yes, i know that if we change the tar command to some thing like below, will works inside the docker

tar -zxOf /tmp/FILENAME.tgz somefiles.txt

Just curious to know why the sysout call “-O” in tar command fails inside the Docker

My practical experience has been that it’s better to extract content like this in the Dockerfile, in a RUN command. The on-disk storage space is the same (especially if you’re docker save into a tar file that will be compressed anyways), and doing this in an entrypoint script adds complexity and startup time.

I’m pretty sure this means what it says: whatever file is in /tmp/FILENAME.tgz in the container doesn’t have a member named FILENAME.tgz. You might add a line like tar tvzf /tmp/FILENAME.tgz before this in the entrypoint script to dump out what’s in the tar file.

The script defined as your entry point is executed in the context of the container, and my best guess would be that /tmp/FILENAME.tgz is in that location on the host?

Would be nice if you could share your Dockerfile, giving a little bit more context to your question.

Make sure you are getting the arguments correct for the version of tar you are using. While similar in effect GNU tar, BSD (OSX default) tar, and Busybox tar are all different programs with varying CLI options.

Here is the Dockerfile i have changed a little. Instead of the entrypoint i run the installation in RUN context.

Anyhow the result will be the same :frowning:

FROM centos:6.6
MAINTAINER vnarasimhan
ADD IP.22.0.1005.ip20160829.Linux-x86_64.tar.gz /tmp
ADD Rel_22.0_1.1005.Linux-x86_64.bin /tmp
ADD installation.conf /tmp
RUN yum install -y tar ksh perl
RUN chmod 755 /tmp/Rel_22.0_1.1005.Linux-x86_64.bin
WORKDIR /tmp
RUN ./Rel_22.0_1.1005.Linux-x86_64.bin -patch IP.22.0.1005.ip20160829.Linux-x86_64.tar.gz installation.conf
ENTRYPOINT ["/bin/bash"]

The exec file Rel_22.0_1.1005.Linux-x86_64.bin has a long shell and binary combined script , where one of the code snippet that has the issue is below

make sure the specified file is an installation patch file.

INTERN_PATCH_FILENAME=`basename $PATCH_FILENAME`
tar -zxOf $PATCH_FILENAME $INTERN_PATCH_FILENAME | tar -zxf - manifest.txt 1>/dev/null 2>&1
RET=$?
if [ "$RET" = "0" ]
then
  if [ -e "manifest.txt" ]
  then
    VERSION=`cat manifest.txt | grep VERSION | sed s/VERSION=//`
    PLATFORM=`cat manifest.txt | grep PLATFORM | sed s/PLATFORM=//`
    #No need for the file anymore
    rm -f manifest.txt
    if [ "$VERSION" != "$BW_VERSION" ] || [ "$PLATFORM" != `uname` ]
    then
      printf "\n  +++ERROR: Invalid installation patch file. This patch file is for version $VERSION and $PLATFORM.\n"
      exit $RC_INVALID_INSTALL_PATCH
    else
      # The patch is valid, check if it contains a validation script.
      tar -zxOf $PATCH_FILENAME $INTERN_PATCH_FILENAME | tar -zxf - self_extract_validation.sh 1>/dev/null 2>&1
      RET=$?
      if [ "$RET" = "0" ] && [ -e "self_extract_validation.sh" ]
      then
        chmod +x self_extract_validation.sh
        LOCAL_PATH=`pwd`
        VALIDATION_SCRIPT="$LOCAL_PATH/self_extract_validation.sh"
      fi
    fi
  else
    printf "\n  +++ERROR: Invalid installation patch file. Patch file does not contain a manifest file.\n"
    exit $RC_INVALID_INSTALL_PATCH
  fi
else
  printf "\n  +++ERROR: Invalid installation patch file. Failed to extract patch.\n"
  exit $RC_INVALID_INSTALL_PATCH
fi

fi

The tar command they used with option “-O” has the issue inside docker.

Modify the Code .bin is merely impossible. Any other way to solve this issue from Dockerfile itself without touching the code

The Options are correct in tar inside the Docker

docker run -it --privileged ums:latest
[root@2fd55480049f tmp]# tar --help
Usage: tar [OPTION…] [FILE]…
GNU `tar’ saves many files together into a single tape or disk archive, and can
restore individual files from the archive.

Examples:
tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.
tar -tvf archive.tar # List all files in archive.tar verbosely.
tar -xf archive.tar # Extract all files from archive.tar.

Main operation mode:

-A, --catenate, --concatenate append tar files to an archive
-c, --create create a new archive
-d, --diff, --compare find differences between archive and file system
–delete delete from the archive (not on mag tapes!)
-r, --append append files to the end of an archive
-t, --list list the contents of an archive
–test-label test the archive volume label and exit
-u, --update only append files newer than copy in archive
-x, --extract, --get extract files from an archive

Operation modifiers:

  --check-device         check device numbers when creating incremental
                         archives (default)

-g, --listed-incremental=FILE handle new GNU-format incremental backup
-G, --incremental handle old GNU-format incremental backup
–ignore-failed-read do not exit with nonzero on unreadable files
–level=NUMBER dump level for created listed-incremental archive
-n, --seek archive is seekable
–no-check-device do not check device numbers when creating
incremental archives
–no-seek archive is not seekable
–occurrence[=NUMBER] process only the NUMBERth occurrence of each file
in the archive; this option is valid only in
conjunction with one of the subcommands --delete,
–diff, --extract or --list and when a list of
files is given either on the command line or via
the -T option; NUMBER defaults to 1
–sparse-version=MAJOR[.MINOR]
set version of the sparse format to use (implies
–sparse)
-S, --sparse handle sparse files efficiently

Overwrite control:

-k, --keep-old-files don’t replace existing files when extracting,
treat them as errors
–keep-newer-files don’t replace existing files that are newer than
their archive copies
–no-overwrite-dir preserve metadata of existing directories
–overwrite overwrite existing files when extracting
–overwrite-dir overwrite metadata of existing directories when
extracting (default)
–recursive-unlink empty hierarchies prior to extracting directory
–remove-files remove files after adding them to the archive
–skip-old-files don’t replace existing files when extracting,
silently skip over them
-U, --unlink-first remove each file prior to extracting over it
-W, --verify attempt to verify the archive after writing it

Select output stream:

  --ignore-command-error ignore exit codes of children
  --no-ignore-command-error   treat non-zero exit codes of children as
                         error

-O, --to-stdout extract files to standard output
–to-command=COMMAND pipe extracted files to another program

@vinothub

If this is the error you’re getting, it seems to be the case that $FILENAME.gz is not found in the archive (like @dmaze mentioned). Docker doesn’t seem to have anything to do with that.

However, I think I might know what your issue is. You are ADD-ing the files in the Dockerfile. If you ADD in a tar archive Docker will automatically extract it, so no such archive exists inside the container image you have. You probably want to COPY them in instead.

Hi Nathan,

I tried that too. The result be the same . Something triggers when use “-O” sysout option inside docker.

All the files are exist in the /tmp directory of the container.

root@a099528b04c7 tmp]# ls

installation.conf IP.22.0.1005.ip20160829.Linux-x86_64.tar.gz Rel_22.0_1.1005.Linux-x86_64.bin

[root@a099528b04c7 tmp]# tar -zxOf /tmp/IP.22.0.1005.ip20160829.Linux-x86_64.tar.gz IP.22.0.1005.ip20160829.Linux-x86_64.tar.gz | tar -zxf - manifest.txt
tar: IP.ums.22.0.1005.ip20160829.Linux-x86_64.tar.gz: Not found in archive
tar: Exiting with failure status due to previous errors