-
Notifications
You must be signed in to change notification settings - Fork 118
/
Copy pathbuild-logs.sh
executable file
·175 lines (134 loc) · 5.68 KB
/
build-logs.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/bin/bash
# Copyright The Shipwright Contributors
#
# SPDX-License-Identifier: Apache-2.0
set -euo pipefail
# Read the build run name
if [ $# -eq 0 ]; then
echo "Usage: build-logs <BUILD_RUN_NAME> [-f|--follow] [-n|--namespace <NAMESPACE_NAME>] [--timestamps]"
exit 1
fi
BUILD_RUN_NAME=$1
shift
# Read the other arguments
FOLLOW=0
NAMESPACE=
TIMESTAMPS=0
while [[ $# -gt 0 ]]
do
ARGKEY="$1"
if [ "${ARGKEY}" == "-f" ] || [ "${ARGKEY}" == "--follow" ]; then
FOLLOW=1
shift
elif [ "${ARGKEY}" == "-n" ] || [ "${ARGKEY}" == "--namespace" ]; then
NAMESPACE=$2
shift
shift
elif [ "${ARGKEY}" == "--timestamps" ]; then
TIMESTAMPS=1
shift
else
echo "Usage: build-logs <BUILD_RUN_NAME> [-f|--follow] [-n|--namespace <NAMESPACE_NAME>] [--timestamps]"
exit 1
fi
done
# Retrieve the namespace if none was provided, use the kubeconfig's current context and fall back to default
# if nothing is set. This is the same logic that a kubectl get would do. Do not use kubectl namespace here as
# the user might not be allowed to read them.
if [ "${NAMESPACE}" == "" ]; then
CONFIG=$(kubectl config view -o json)
CURRENT_CONTEXT=$(echo "${CONFIG}" | jq -r '.["current-context"]')
NAMESPACE=$(echo "${CONFIG}" | jq -r ".contexts[] | select(.name == \"${CURRENT_CONTEXT}\") | .context.namespace")
if [ "${NAMESPACE}" == "null" ]; then
NAMESPACE=default
fi
fi
# Verify the build run exists
if ! kubectl get buildrun "${BUILD_RUN_NAME}" -n "${NAMESPACE}" >/dev/null 2>&1; then
echo "A build run with the name '${BUILD_RUN_NAME}' cannot be found in the namespace '${NAMESPACE}'."
exit 2
fi
echo "Build run: ${BUILD_RUN_NAME}"
# Extract the task run name from the buildrun
TASK_RUN_NAME=$(kubectl get buildrun "${BUILD_RUN_NAME}" -n "${NAMESPACE}" -o json | jq -r '.status.latestTaskRunRef')
echo "Task run: ${TASK_RUN_NAME}"
# Find the pod, it has labels for the build run and task run name
PODS=$(kubectl get pods -l "buildrun.shipwright.io/name=${BUILD_RUN_NAME},tekton.dev/taskRun=${TASK_RUN_NAME}" -n "${NAMESPACE}" -o json)
PODS_LENGTH=$(echo "${PODS}" | jq ".items | length")
if [ "${PODS_LENGTH}" -eq 0 ]; then
echo "No pod found. There is probably a problem in your build configuration."
exit 3
elif [ "${PODS_LENGTH}" -ne 1 ]; then
echo "More than one pod found, that's unexpected."
exit 4
fi
POD=$(echo "${PODS}" | jq ".items[0]")
POD_NAME=$(echo "${POD}" | jq -r ".metadata.name")
echo "Pod: ${POD_NAME}"
echo
# Retrieve the number of containers
CONTAINERS_LENGTH=$(echo "${POD}" | jq ".spec.containers | length")
# Iterate the containers
for (( i = 0; i < CONTAINERS_LENGTH; i++ ))
do
# Extract the container name
CONTAINER_NAME=$(echo "${POD}" | jq -r ".spec.containers[${i}].name")
echo "Logs of container ${CONTAINER_NAME}:"
echo
# Check if the container is waiting
WAITING_REASON=$(echo "${POD}" | jq -r ".status.containerStatuses[] | select(.name == \"${CONTAINER_NAME}\") | .state.waiting.reason")
if [ "${WAITING_REASON}" != "null" ]; then
# In follow mode, wait for the container not to be waiting anymore, otherwise stop here
if [ ${FOLLOW} = 1 ]; then
while [ "${WAITING_REASON}" != "null" ]; do
echo "Container is not yet running. Waiting reason: ${WAITING_REASON}"
sleep 1
POD=$(kubectl get pod "${POD_NAME}" -n "${NAMESPACE}" -o json)
WAITING_REASON=$(echo "${POD}" | jq -r ".status.containerStatuses[] | select(.name == \"${CONTAINER_NAME}\") | .state.waiting.reason")
done
else
echo "Container is not yet running. Waiting reason: ${WAITING_REASON}"
echo
break
fi
fi
# Extract the exit code of the container
EXIT_CODE=$(echo "${POD}" | jq ".status.containerStatuses[] | select(.name == \"${CONTAINER_NAME}\") | .state.terminated.exitCode")
if [ ${FOLLOW} = 1 ] && [ "${EXIT_CODE}" == "null" ]; then
# Container is still running and follow logs is requested
if [ ${TIMESTAMPS} = 1 ]; then
kubectl logs "${POD_NAME}" "${CONTAINER_NAME}" -f -n "${NAMESPACE}" --timestamps
else
kubectl logs "${POD_NAME}" "${CONTAINER_NAME}" -f -n "${NAMESPACE}"
fi
# Refresh the pod to get the exit code of the container, sometimes this takes a moment
while [ "${EXIT_CODE}" == "null" ]; do
POD=$(kubectl get pod "${POD_NAME}" -n "${NAMESPACE}" -o json)
EXIT_CODE=$(echo "${POD}" | jq ".status.containerStatuses[] | select(.name == \"${CONTAINER_NAME}\") | .state.terminated.exitCode")
done
else
# Just print the logs that we have
if [ ${TIMESTAMPS} = 1 ]; then
kubectl logs "${POD_NAME}" "${CONTAINER_NAME}" -n "${NAMESPACE}" --timestamps
else
kubectl logs "${POD_NAME}" "${CONTAINER_NAME}" -n "${NAMESPACE}"
fi
if [ "${EXIT_CODE}" == "null" ]; then
# Refresh the pod to get the exit code of the container if it terminated in the meantime
POD=$(kubectl get pod "${POD_NAME}" -n "${NAMESPACE}" -o json)
EXIT_CODE=$(echo "${POD}" | jq ".status.containerStatuses[] | select(.name == \"${CONTAINER_NAME}\") | .state.terminated.exitCode")
fi
fi
echo
# Print a message depending on the exit code
if [ "${EXIT_CODE}" == "null" ]; then
echo "Container is still running."
echo
break
elif [ "${EXIT_CODE}" == "0" ]; then
echo "Container terminated successfully."
else
echo "Container terminated with an error. Status code: ${EXIT_CODE}"
fi
echo
done