Docker cli: docker run command with quoted arguments - docker

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

Related

how to trigger and monitor Jenkins job from CI and getting results after is finished

I am trying to implement a script in gitlab CI to trigger a smoke test via Jenkins and then get the results.
So far I am able to trigger the job successfully and I am trying to follow this to implement a monitoring stage and then get the result once the job finishes.
my issue is that I implemented a while loop to monitor if the Jenkins job has finished so far the script is giving either syntax errors (when copied in gitlab) or if run in the terminal I get:
job is building? true
waiting...
parse error: Invalid numeric literal at line 2, column 0
job is still building?
job is building?
This is what I am using so far:
#!/bin/bash
running="true"
while [ "$running" != "false" ]
do
echo "job is building? ${running}"
echo "waiting...";
sleep 2;
running=$(curl -s --user ${EMAIL}:${TOKEN} ${URL}/${var}/lastBuild/api/json | jq .'building')
echo "job is still building? ${running}"
done
echo "Done!"
buildNumber=$(curl -s --user $EMAIL:$TOKEN ${URL}/$ENV-${var}/lastBuild/api/json | jq ".url" | awk -F "/" '{print $(NF-1)}')
echo "getting results for build ${buildNumber}"
curl -s --user ${EMAIL}:${TOKEN} ${URL}/${ENV}-${var}/lastBuild/api/json | jq ".url" | awk -F "/" '{print $(NF-1)}'
curl -v --silent --user ${EMAIL}:${TOKEN} ${URL}/${ENV}-${var}/lastBuild/consoleText 2>&1 | grep -i "finished:"
UPDATE
the script is running now ok in my local terminal
the change was
running="true"
while [ "$running" != "false" ]
do
echo "job is building? ${running}"
echo "waiting..."
sleep 2
curl -s --user $EMAIL:$TOKEN $URL/$ENV-${var}/lastBuild/api/json --output now.txt
running=$(jq .'building' now.txt)
echo "job is still building? ${running}"
done
The problem is still on Gitlab CI as after copy pasting this script I get in the pipeline
/bin/sh: eval: line 149: syntax error: unexpected "done"
I'm guessing that the error
parse error: Invalid numeric literal at line 2, column 0
comes from the line that does the curl
running=$(curl -s --user ${EMAIL}:${TOKEN} ${URL}/${var}/lastBuild/api/json | jq .'building')`
I'm assuming that the error is thrown by jq when it tries to parse the json and fails. Since this line has an error, the variable running never gets properly updated, meaning that the rest of the script doesn't work as intended.
If you fix this line, the rest of your pipeline should work. Consider looking into this question which has a similar problem and some solutions.

Why does docker fail to run correct CMD when using .sh script as entrypoint?

I'm relatively new to docker (at least to do more than run images others had built) and I'm stuck on this one. I'm building an app using Deno and trying to get it running in docker. my base image is the official deno image with Alpine, which uses an .sh as its entry point. The entry point script as defined in the official image is supposed to look at the first argument in the CMD (in this case "run") and if it's in a list (which it is), run it with the deno command. Instead I get an error.
the CMD
CMD run --allow-net --allow-read --lock=lock.json mod.ts
the error
/bin/sh: run: not found
when I hard code in the deno, it runs fine.
CMD deno run --allow-net --allow-read --lock=lock.json mod.ts
I can't figure why it's not working through the script as an entry point. What am I doing wrong?
docker-entry.sh
#!/bin/sh
set -e
if [ "$1" != "${1#-}" ]; then
# if the first argument is an option like `--help` or `-h`
exec deno "$#"
fi
case "$1" in
bundle | cache | compile | completions | coverage | doc | eval | fmt | help | info | install | lint | lsp | repl | run | test | types | uninstall | upgrade | vendor )
# if the first argument is a known deno command
exec deno "$#";;
esac
exec "$#"
my Dockerfile
FROM denoland/deno:alpine-1.19.2
# The port that your application listens to.
EXPOSE MYPORTNUMBER
WORKDIR /app
# Prefer not to run as root.
USER deno
# Cache the dependencies as a layer (the following two steps are re-run only when deps.ts is modified).
# Ideally cache deps.ts will download and compile _all_ external files used in main.ts.
COPY deps.ts .
RUN deno cache deps.ts
# These steps will be re-run upon each file change in your working directory:
ADD . .
# Compile the main app so that it doesn't need to be compiled each startup/entry.
RUN deno cache mod.ts
CMD run --allow-net --allow-read --lock=lock.json mod.ts
base image info here

grep command with regex not working on gitlab ci

I am running script in my gitlab ci:
pre_build:
stage: get_info
script:
- printenv
- cd ./scripts
- ./pre_build.sh
this script has the following line:
todays_date=$(date +"%d-%b-%Y")
latest=$(curl -i ${artifactory_url} | grep develop | grep -i ${todays_date} | grep ${last_ok_build_number} | grep -Eoi '<a [^>]+>' | grep -Eo 'href="[^\"]+"')
I believe this is failing due to regex in grep, any idea how to run this in GitLab ci?
Above script works perfectly well on my local machine
EDIT: Above codes works it was timezone issue

Rebuild a docker image depending on the output of a command

Say I want to rebuild my docker image when a new compiler version is available in some repository.
I can gather the version inside the container:
FROM centos:7
RUN yum info gcc | grep Version | sort | tail -1 | cut -d: -f2 | tr -d ' '
If I build this container and tag it as base, I can use that information and setup a second container:
FROM base
RUN yum install gcc-4.8.5
Docker will be able to cache the second container and not rebuild it, when the compiler version has not changed. But creating that requires some shell scripting and that might be brittle in, e.g., a continuous integration scenario.
What I would like to do is to introduce a unified source for these two containers. Is there a way to write something like this:
FROM centos:7
$GCC_VERSION=RUN yum info gcc | grep Version | sort | tail -1 | cut -d: -f2 | tr -d ' '
RUN yum install gcc-$GCC_VERSION
and have the variables expanded (and the commands still cached) during docker build ?
You can use the ARG instruction. Build args affect the cache in the way you want to: Impact on build caching
With a Dockerfile like this:
FROM centos:7
ARG GCC_VERSION
RUN yum install -y gcc-$GCC_VERSION
The image gets only rebuilt if the GCC_VERSION changes.
docker build --build-arg GCC_VERSION=$(docker run centos:7 yum info gcc | grep Version | sort | tail -1 | cut -d: -f2 | tr -d ' ') .

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