Mark Gitlab CI stage as passed based on condition in job log - bash

I have a bash script that is executing a dataflow job like so
/deploy.sh
python3 main.py \
--runner DataflowRunner \
--region us-west1 \
--job_name name \
--project project \
--autoscaling_algorithm THROUGHPUT_BASED \
--max_num_workers 10 \
--environment prod \
--staging_location gs staging loc \
--temp_location temp loc \
--setup_file ./setup.py \
--subnetwork subnetwork \
--experiments use_network_tags=internal-ssh-server
So I use gitlab ci to run this
./gitlab-ci.yml
Deploy Prod:
stage: Deploy Prod
environment: production
script:
- *setup-project
- pip3 install --upgrade pip;
- pip install -r requirements.txt;
- chmod +x deploy.sh
- ./deploy.sh
only:
- master
So now my code runs and logs in the gitlab pipeline AND in the logs viewer in dataflow. What I want to be able to do is that once gitlab sees JOB_STATE_RUNNING, it marks the pipeline as passed and stops outputting logs to gitlab. Maybe there's a way to do this in the bash script? Or can it be done in gitlab ci?

GitLab doesn't have this capability as a feature, so your only is to script the solution.
Something like this should work to monitor the output and exit once that text is encountered.
python3 myscript.py > logfile.log &
( tail -f -n0 logfile.log & ) | grep -q "JOB_STATE_RUNNING"
echo "Job is running. We're done here"
exit 0
reference: https://superuser.com/a/900134/654263
You'd need to worry about some other things in the script, but that's the basic idea. GitLab unfortunately has no success condition based on trace output.

Little late, hope this helps someone, The way i solved it was I created two scripts
build.sh
#!/bin/bash
# This helps submit the beam dataflow job using nohup and parse the results for job submission
nohup stdbuf -oL bash ~/submit_beam_job.sh &> ~/output.log &
# Wait for log file to appear before checking on it
sleep 5
# Count to make sure the while loop is not stuck
cnt=1
while ! grep -q "JOB_STATE_RUNNING" ~/output.log; do
echo "Job has not started yet, waiting for it to start"
cnt=$((cnt+1))
if [[ $cnt -gt 5 ]]; then
echo "Job submission taking too long please check!"
exit 1
fi
# For other error on the log file, checking the keyword
if grep -q "Errno" ~/output.log || grep -q "Error" ~/output.log; then
echo "Error submitting Dataflow job, please check!!"
exit 1
fi
sleep 30
done
The submit beam job is like this
#!/bin/bash
# This submits individual beam jobs for each topics
export PYTHONIOENCODING=utf8
# Beam pipeline for carlistingprimaryimage table
python3 ~/dataflow.py \
--input_subscription=projects/data-warehouse/subscriptions/cars \
--window_size=2 \
--num_shards=2 \
--runner=DataflowRunner \
--temp_location=gs://bucket/beam-python/temp/ \
--staging_location=gs://bucket/beam-python/binaries/ \
--max_num_workers=5 \
--project=data-warehouse \
--region=us-central1 \
--gcs_project=data-warehouse \
--setup_file=~/setup.py

Related

Does not getting build failure status even the build not successful run(cloud-build remote builder)

Cloud-build is not showing build failure status
I created my own remote-builder which scp all files from /workspace to my Instance and running build on using gcloud compute ssh -- COMMAND
remote-builder
#!/bin/bash
USERNAME=${USERNAME:-admin}
REMOTE_WORKSPACE=${REMOTE_WORKSPACE:-/home/${USERNAME}/workspace/}
GCLOUD=${GCLOUD:-gcloud}
KEYNAME=builder-key
ssh-keygen -t rsa -N "" -f ${KEYNAME} -C ${USERNAME} || true
chmod 400 ${KEYNAME}*
cat > ssh-keys <<EOF
${USERNAME}:$(cat ${KEYNAME}.pub)
EOF
${GCLOUD} compute scp --compress --recurse \
$(pwd)/ ${USERNAME}#${INSTANCE_NAME}:${REMOTE_WORKSPACE} \
--ssh-key-file=${KEYNAME}
${GCLOUD} compute ssh --ssh-key-file=${KEYNAME} \
${USERNAME}#${INSTANCE_NAME} -- ${COMMAND}
below is the example of the code to run build(cloudbuild.yaml)
steps:
- name: gcr.io/$PROJECT_ID/remote-builder
env:
- COMMAND="docker build -t [image_name]:[tagname] -f Dockerfile ."
During docker build inside Dockerfile it got failure and show errors in log but status showing SUCCESS
can any help me how to resolve it.
Thanks in advance.
try adding
|| exit 1
at the end of your docker command... alternatively, you might just need to change the entrypoint to 'bash' and run the script manually
To confirm -- the first part was the run-on.sh script, and the second part was your cloudbuild.yaml right? I assume you trigger the build manually via UI and/or REST API?
I wrote all docker commands on bash script and add below error handling code to it.
handle_error() {
echo "FAILED: line $1, exit code $2"
exit 1
}
trap 'handle_error $LINENO $?' ERR
It works!

Cannot reach port of gcloud appengine devserver

for testing I try to run the gcloud devserver inside docker with that comment:
sudo /usr/local/gcloud/google-cloud-sdk/bin/java_dev_appserver.sh --disable_update_check --port=8888 --help /app/target/qdacity-war/ 2>&1 | sudo tee /app/logs/devserver.log > /dev/null &
To check if the devserver has started successfully, I use this script:
#!/bin/bash
# This script waits until the port 8888 is open.
SERVER=localhost
PORT=8888
TIMEOUT=180
TIME_INTERVAL=2
PORT_OPEN=1
PORT_CLOSED=0
time=0
isPortOpen=0
while [ $time -lt $TIMEOUT ] && [ $isPortOpen -eq $PORT_CLOSED ];
do
# Connect to the port
(echo > /dev/tcp/$SERVER/$PORT) >/dev/null 2>&1
if [ $? -ne 0 ]; then
isPortOpen=$PORT_CLOSED
else
isPortOpen=$PORT_OPEN
fi
time=$(($time+$TIME_INTERVAL))
sleep $TIME_INTERVAL
done
if [ $isPortOpen -eq $PORT_OPEN ]; then
echo "Port is open after ${time} seconds."
# Give the server more time to properly start
sleep 10
else
echo "Reached the timeout (${TIMEOUT} seconds). The port ${SERVER}:${PORT} is not available."
exit 1
fi
After running all the test, I just got back:
Reached the timeout (180 seconds). The port localhost:8888 is not available.
I couldn't find out if there were any problems starting the devserver or querying the port.
Does anyone have an idea or solution?
Thanks!
By default, by only accepting localhost|loopback traffic, you're unable to access the server remotely.
Please try adding --address=0.0.0.0:
(link) to your java_dev_appserver.sh command.
Example
Used a variant of Google's HelloWorld sample.
Ran this with mvn appengine:run (to confirm it works and build the WAR).
Then /path/to/bin/java_dev_appserver.sh ./target/hellofreddie-0.1 (to confirm it works with the local development server).
Then used Google's Cloud SDK container image (link), mounted the previously generated WAR directory into it, and ran the server on :9999:
docker run \
--interactive \
--tty \
--publish=9999:9999 \
--volume=${PWD}/target:/target \
google/cloud-sdk \
/usr/lib/google-cloud-sdk/bin/java_dev_appserver.sh \
--address=0.0.0.0 \
--port=9999 \
./target/hellofreddie-0.1
Am able to curl the endpoint:
curl \
--silent \
--location \
--write-out "%{http_code}" \
--output /dev/null \
localhost:9999
returns 200
And, running your scripts adjusted with PORT=9999 returns:
Port is open after 2 seconds.

Organization of commands in makefile

I have the following command which runs integration tests:
run-it:
docker-compose -f docker-compose-tests.yml pull && \
docker-compose -f docker-compose-tests.yml up --build & \
sleep 150s && dotnet test --filter TestCategory=Integration.Tests $(SOLUTION) ; docker-compose -f docker-compose-tests.yml down
I want:
pull all containers
run docker compose in background
run integrations tests in 150 seconds.
But it looks that test start running before the pull command is completed.
I want 1 point run first, then 2 started and 3 start in 150 seconds after 2 is started.
Before worrying about make you should ensure that you can run the commands correctly from the shell prompt. In this case you're misunderstanding how the background token & works; it applies to the entire previous section of the command. Basically, you're running the equivalent of this:
( docker-compose -f docker-compose-tests.yml pull && \
docker-compose -f docker-compose-tests.yml up --build ) & \
sleep 150s && ...
Since you've put both the pull and the up into the background, the sleep and tests start running concurrently to the pull.
Try adding some parens to put the backgrounded process into a subshell:
docker-compose -f docker-compose-tests.yml pull && \
( docker-compose -f docker-compose-tests.yml up --build & ) && \
sleep 150s && ...

“How to fix ‘Syntax Error Near’ error in BASH”

I'm setting a new condition for run delete job if exist but don't work in production case.
GNU bash, v4.3.48(1)-release (x86_64-pc-linux-gnu)
docker run -e GO_DEPENDENCY_LABEL_PIPE='XXXXX' -e CREDENTIAL_NAME='production.XXXXX' -e KUBE_TOKEN='XXXXX' -v /go/pipelines/deploy-portal-site-data/helm:/helm --add-host=api.production.XXXXX:00.000.000.000 --rm -t --entrypoint /bin/bash docker.XXXXX.com.br/kubectl-prod:latest --login -c "kubectl config set-credentials production.XXXXX --token=XXXXX; VerifyJob=0; [[ -ge 1 ]] && kubectl -n production delete job portal-site-data-production || echo 'There is no job at the moment'"
I expect the output of clean job, but the actual output is
Creating /root/.helm/repository
Creating /root/.helm/repository/cache
Creating /root/.helm/repository/local
Creating /root/.helm/starters
Creating /root/.helm/cache/archive
Creating /root/.helm/repository/repositories.yaml
Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
Adding local repo with URL: http://127.0.0.1:8879/charts
$HELM_HOME has been configured at /root/.helm.
Not installing Tiller due to 'client-only' flag having been set
Happy Helming!
Hang tight while we grab the latest from your chart repositories...
...Skip local chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈ Happy Helming!⎈
"gfn-helm-repo" has been added to your repositories
/bin/bash: -c: line 0: conditional binary operator expected
/bin/bash: -c: line 0: syntax error near `1'
/bin/bash: -c: line 0: `kubectl config set-credentials production.XXXXX --token=XXXXX; VerifyJob=0; [[ -ge 1 ]] && kubectl -n production delete job portal-site-data-production || echo 'There is no job at the moment''
[[ -ge 1 ]]
I think the error comes from this part of the command.
It is testing if "undefined" is greater or equal to 1
I deleted my chart
helm delete portal-site-data-production --tiller-namespace production --purge
and put \ before the "
set -x
docker pull $DOCKER_HELM_PROD_IMAGE
docker run \
-e GO_DEPENDENCY_LABEL_PIPE='${GO_DEPENDENCY_LABEL_PIPE}' \
-e CREDENTIAL_NAME='${CREDENTIAL_NAME}' \
-e KUBE_TOKEN='${KUBE_TOKEN}' \
-v $PWD/helm:/helm \
--add-host=api.production.XXXXX:00.000.000.000 \
--rm -t --entrypoint /bin/bash \
$DOCKER_HELM_PROD_IMAGE \
--login -c "kubectl config set-credentials ${CREDENTIAL_NAME} --token=${KUBE_TOKEN}; VerifyJob=$(kubectl -n production get job| grep -c portal-site-data-production); \"[[ ${VerifyJob} -ge 1 ]]\" && kubectl -n production delete job portal-site-data-production || echo \"There is no job at the moment\""
This Ok now, thank you very much to everyone.

How to check whether a docker service is already running on UCP using shell script

I want to check whether a docker service is running or not.
if it's running I want to remove that service and create the new one
I am doing this task with shell script
I am providing the code snippet of my shell script where I am facing
Error response from daemon: service data-mapper-service not found
if [[ "$(docker service inspect ${DOCKER_SERVICE_NAME} 2> /dev/null)" != "" ]]; then
docker service rm ${DOCKER_SERVICE_NAME}
else echo "service doesn't exist or may have been removed manually"
fi
docker service create \
--name ${DOCKER_SERVICE_NAME} \
--network ${OVERLAY_NETWORK} \
--reserve-memory ${10} \
--constraint node.labels.run_images==yes \
--mode global \
--with-registry-auth \
--restart-condition any \
-p ${EXTERNAL_PORT}:${INTERNAL_PORT} \
-e "SPRING_PROFILES_ACTIVE="${SPRING_PROFILE} \
-e "JAVA_OPTS: -Xms256m -Xmx512m" \
${DTR_HOST_NAME}/${DTR_ORG_NAME}/${DTR_REP_NAME}:${BUILD_NUMBER}
I am getting the error on if statement line.
If the service is running and I trigger this shell script everything runs fine, But if the service is not running and I trigger this shell script I am facing above mention error.

Resources