piped sh command causing docker build script to choke - docker

I've got this in a docker build file: RUN 'echo "y" | /usr/bin/task'
When building, this error is thrown:
=> ERROR [tool_config 9/11] RUN 'echo "y" | /usr/bin/task' 0.2s
------
> [tool_config 9/11] RUN 'echo "y" | /usr/bin/task':
#15 0.164 /bin/sh: echo "y" | /usr/bin/task: not found
------
executor failed running [/bin/sh -c 'echo "y" | /usr/bin/task']: exit code: 127
The command runs fine when manually run from insside the container. The task command is definitely installed.
Without without quotes, RUN echo "y" | task gives:
=> ERROR [tool_config 9/11] RUN echo "y" | /usr/bin/task 0.2s
------
> [tool_config 9/11] RUN echo "y" | /usr/bin/task:
#15 0.176 A configuration file could not be found in /root
#15 0.176
#15 0.176 Would you like a sample /root/.taskrc created, so Taskwarrior can proceed? (yes/no) No matches.
------
executor failed running [/bin/sh -c echo "y" | /usr/bin/task]: exit code: 1

The problem was the task command was returning "No matches" because no tasks had yet been created so the command exited with an error code of 1 and docker choked.
Fix is simple as per https://stackoverflow.com/a/30717108/1641112:
RUN echo "y" | task; exit 0;

Related

How to use docker-abuild in a Dockerfile?

I want to use docker-abuild to build imagemagick in a Dockerfile. I use the following in the Dockerfile:
FROM alpinelinux/docker-abuild as imagickbuilder
COPY imagick/APKBUILD.imagick /home/builder/package/APKBUILD
COPY imagick/APKBUILD.imagick /home/builder/APKBUILD
COPY imagick/disable-avaraging-tests.patch /home/builder/package/disable-avaraging-tests.patch
COPY imagick/webmaster#mycompany.com-5b42f8ed.rsa /home/builder/ssh.rsa
COPY imagick/webmaster#mycompany.com-5b42f8ed.rsa.pub /etc/apk/keys/ssh.rsa.pub
ARG DABUILD_ARCH=aarch64
RUN dabuild -r
# tried abuild -r as well as builder -r
Regardless of what APKBUILD file I have/use, I'm getting the following error while building with docker build -t test .:
#...
#11 [7/7] RUN dabuild -r
#11 sha256:8c6e0fa4c055b4f5bbb7f633a3b4b4009cda31017a26dc48a047fd02466ce60c
#11 0.658 /bin/sh: dabuild: not found
#11 ERROR: executor failed running [/bin/sh -c dabuild -r]: exit code: 127
------
> [7/7] RUN dabuild -r:
------
executor failed running [/bin/sh -c dabuild -r]: exit code: 127
I'm getting the same error with abuild -r and abuilder -r. Any ideas?
JFYI, I'm running this under macOS Monterey 12.2.1 with an M1 Pro MacBook Pro.

Syntax error while running shell script via Dockerfile

While executing the run command, I'm getting syntax error as follows:
> [10/10] RUN ./download_files.sh:
#15 0.285 ./download_files.sh: 5: ./download_files.sh: Syntax error: "(" unexpected
------
executor failed running [/bin/sh -c ./download_files.sh]: exit code: 2
The Shell script contents are as follows:
#!/bin/sh
mkdir pretrained_models
cd pretrained_models
declare -a StringArray=("https://zenodo.org/record/4751737/files/BC-DeepLIIF_Training_Set.zip" "https://zenodo.org/record/4751737/files/BC-DeepLIIF_Validation_Set.zip" "https://zenodo.org/record/4751737/files/DeepLIIF_BC_Model.zip" "https://zenodo.org/record/4751737/files/DeepLIIF_Latest_Model.zip" "https://zenodo.org/record/4751737/files/DeepLIIF_Testing_Set.zip" "https://zenodo.org/record/4751737/files/DeepLIIF_Training_Set.zip" "https://zenodo.org/record/4751737/files/DeepLIIF_Validation_Set.zip" "https://zenodo.org/record/4751737/files/Evaluation_Excel_Files.zip")
for val in ${StringArray[#]}; do
exec wget $val
done

Why is wc -l returning 0 in a sh step subshell in Jenkins/groovy

I have a Jenkins script that looks like this
stage ("Build and Deploy") {
steps {
script {
def statusCode = sh(script:"""ssh ${env.SERVER_NAME} << EOF
cd ${env.LOCATION}
git clone -b ${env.GIT_BRANCH} ${env.GIT_URL} ${env.FOLDER}
cd ${env.FOLDER}
... some other stuff goes here but isnt relevant ..
sudo docker-compose up -d --build
if [ ! \$(sudo docker container ls -f "name=config-provider-*" | wc -l ) -eq 4 ]
then
exit 1
fi
""", returnStatus:true).toString().trim()
if (statusCode == "1") {
error("At least one container failed to start")
}
}
}
}
What I want is to exit with error code 1 in the script if the number of running containers is not equal to 3 (wc -l == 4 including the header), but the if statement is evaluating true and exiting with error code 1 even though i know that the containers are successfully running.
I have tried
echo sh(script: """ssh ${env.SERVER_NAME} << EOF
echo \$(sudo docker container ls -f "name=config-provider-*" | wc -l)
""", returnStdout:true).toString()
and
echo sh(script: """ssh ${env.SERVER_NAME} << EOF
echo \$(sudo docker container ls -f "name=config-provider-*")
""", returnStdout:true).toString()
The latter outputted 4 lines within jenkins showing all of the running containers, as expected, but the former which includes "| wc -l" returned and printed out 0 in jenkins.
I have reproduced the steps of this script line by line manually from start to finish and it works as intended when not run from within jenkins.
Additionally, manually running the command:
[ ! $(sudo docker container ls -f "name=config-provider-*" | wc -l ) -eq 4 ] && echo failed
echoes nothing, and the following command returns an output of 4, which is expected.
echo $(sudo docker container ls -f "name=config-provider-*" | wc -l )

Docker cli: docker run command with quoted arguments

I'm trying to run execute jest -t variant with the following Docker cli command:
docker run -it node-jest npx jest -t "This string matches exactly one test"
Which does not do the same thing if I were to run npx jest -t "This string matches exactly one test" locally.
It appears that double quotes are being stripped/ignored and only This is getting passed to jest -t. It appears that This string matches exactly one test is getting split up on spaces and treated as individual arguments. Can someone explain why that is happening, and how to get "This string matches exactly one test" passed in to docker run correctly (hopefully in a readable/sane way)?
You did not mention the error, and the quotes seems fine and it should work or run the container with shell, but my assumption is you did not set the WORKING directory in your Dockerfile or there is something wrong with Dockerfile
Here is working example taking from jest docker image with some testing code.
docker run -ti adiii717/jest sh -c 'npx jest -t "it should filter by a search term (link)"'
output:
Ran all test suites with tests matching "it should filter by a search term (link)".
-----------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------------|----------|----------|----------|----------|-------------------|
All files | 12.5 | 0 | 0 | 16.67 | |
filterByTerm.js | 12.5 | 0 | 0 | 16.67 | 2,3,4,5,6 |
-----------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 skipped, 0 of 1 total
Tests: 3 skipped, 3 total
Snapshots: 0 total
Time: 1.109s
Ran all test suites with tests matching "it should filter by a search term (link)".
Here is the Dockerfile
FROM node:alpine
RUN apk add --no-cache git
RUN npm install jest npx -g
WORKDIR /app
RUN git clone https://github.com/valentinogagliardi/getting-started-with-jest.git /app
RUN npm install

How to workaround "the input device is not a TTY" when using grunt-shell to invoke a script that calls docker run?

When issuing grunt shell:test, I'm getting warning "the input device is not a TTY" & don't want to have to use -f:
$ grunt shell:test
Running "shell:test" (shell) task
the input device is not a TTY
Warning: Command failed: /bin/sh -c ./run.sh npm test
the input device is not a TTY
Use --force to continue.
Aborted due to warnings.
Here's the Gruntfile.js command:
shell: {
test: {
command: './run.sh npm test'
}
Here's run.sh:
#!/bin/sh
# should use the latest available image to validate, but not LATEST
if [ -f .env ]; then
RUN_ENV_FILE='--env-file .env'
fi
docker run $RUN_ENV_FILE -it --rm --user node -v "$PWD":/app -w /app yaktor/node:0.39.0 $#
Here's the relevant package.json scripts with command test:
"scripts": {
"test": "mocha --color=true -R spec test/*.test.js && npm run lint"
}
How can I get grunt to make docker happy with a TTY? Executing ./run.sh npm test outside of grunt works fine:
$ ./run.sh npm test
> yaktor#0.59.2-pre.0 test /app
> mocha --color=true -R spec test/*.test.js && npm run lint
[snip]
105 passing (3s)
> yaktor#0.59.2-pre.0 lint /app
> standard --verbose
Remove the -t from the docker run command:
docker run $RUN_ENV_FILE -i --rm --user node -v "$PWD":/app -w /app yaktor/node:0.39.0 $#
The -t tells docker to configure the tty, which won't work if you don't have a tty and try to attach to the container (default when you don't do a -d).
This solved an annoying issue for me. The script had these lines:
docker exec **-it** $( docker ps | grep mysql | cut -d' ' -f1) mysql --user= ..... > /var/tmp/temp.file
mutt -s "File is here" someone#somewhere.com < /var/tmp/temp.file
The script would run great if run directly and the mail would come with the correct output. However, when run from cron, (crontab -e) the mail would come with no content. Tried many things around permissions and shells and paths etc. However no joy!
Finally found this:
*/20 * * * * scriptblah.sh > $HOME/cron.log 2>&1
And on that cron.log file found this output:
the input device is not a TTY
Search led me here. And after I removed the -t, it's working great now!
docker exec **-i** $( docker ps | grep mysql | cut -d' ' -f1) mysql --user= ..... > /var/tmp/temp.file

Resources