1
+ #! /usr/bin/env bash
2
+
3
+ # Copyright The kagent Authors.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # The install script is based off of the MIT-licensed script from glide,
18
+ # the package manager for Go: https://github.com/Masterminds/glide.sh/blob/master/get
19
+
20
+ : ${BINARY_NAME:= " kagent" }
21
+ : ${USE_SUDO:= " true" }
22
+ : ${DEBUG:= " false" }
23
+ : ${VERIFY_CHECKSUM:= " true" }
24
+ : ${KAGENT_INSTALL_DIR:= " /usr/local/bin" }
25
+
26
+ HAS_CURL=" $( type " curl" & > /dev/null && echo true || echo false) "
27
+ HAS_WGET=" $( type " wget" & > /dev/null && echo true || echo false) "
28
+ HAS_OPENSSL=" $( type " openssl" & > /dev/null && echo true || echo false) "
29
+ HAS_GPG=" $( type " gpg" & > /dev/null && echo true || echo false) "
30
+ HAS_GIT=" $( type " git" & > /dev/null && echo true || echo false) "
31
+ HAS_TAR=" $( type " tar" & > /dev/null && echo true || echo false) "
32
+ HAS_JQ=" $( type " jq" & > /dev/null && echo true || echo false) "
33
+
34
+ # initArch discovers the architecture for this system.
35
+ initArch () {
36
+ ARCH=$( uname -m)
37
+ case $ARCH in
38
+ armv5* ) ARCH=" armv5" ;;
39
+ armv6* ) ARCH=" armv6" ;;
40
+ armv7* ) ARCH=" arm" ;;
41
+ aarch64) ARCH=" arm64" ;;
42
+ x86) ARCH=" 386" ;;
43
+ x86_64) ARCH=" amd64" ;;
44
+ i686) ARCH=" 386" ;;
45
+ i386) ARCH=" 386" ;;
46
+ esac
47
+ }
48
+
49
+ # initOS discovers the operating system for this system.
50
+ initOS () {
51
+ OS=$( echo ` uname` | tr ' [:upper:]' ' [:lower:]' )
52
+
53
+ case " $OS " in
54
+ # Minimalist GNU for Windows
55
+ mingw* |cygwin* ) OS=' windows' ;;
56
+ esac
57
+ }
58
+
59
+ # runs the given command as root (detects if we are root already)
60
+ runAsRoot () {
61
+ if [ $EUID -ne 0 -a " $USE_SUDO " = " true" ]; then
62
+ sudo " ${@ } "
63
+ else
64
+ " ${@ } "
65
+ fi
66
+ }
67
+
68
+ # verifySupported checks that the os/arch combination is supported for
69
+ # binary builds, as well whether or not necessary tools are present.
70
+ verifySupported () {
71
+ local supported=" darwin-amd64\ndarwin-arm64\nlinux-386\nlinux-amd64\nlinux-arm\nlinux-arm64\nlinux-ppc64le\nlinux-s390x\nlinux-riscv64\nwindows-amd64\nwindows-arm64"
72
+ if ! echo " ${supported} " | grep -q " ${OS} -${ARCH} " ; then
73
+ echo " No prebuilt binary for ${OS} -${ARCH} ."
74
+ echo " To build from source, go to https://github.com/kagent-dev/kagent"
75
+ exit 1
76
+ fi
77
+
78
+ if [ " ${HAS_CURL} " != " true" ] && [ " ${HAS_WGET} " != " true" ]; then
79
+ echo " Either curl or wget is required"
80
+ exit 1
81
+ fi
82
+
83
+ if [ " ${VERIFY_CHECKSUM} " == " true" ] && [ " ${HAS_OPENSSL} " != " true" ]; then
84
+ echo " In order to verify checksum, openssl must first be installed."
85
+ echo " Please install openssl or set VERIFY_CHECKSUM=false in your environment."
86
+ exit 1
87
+ fi
88
+
89
+ if [ " ${HAS_GIT} " != " true" ]; then
90
+ echo " [WARNING] Could not find git. It is required for plugin installation."
91
+ fi
92
+
93
+ if [ " ${HAS_TAR} " != " true" ]; then
94
+ echo " [ERROR] Could not find tar. It is required to extract the kagent binary archive."
95
+ exit 1
96
+ fi
97
+ }
98
+
99
+ # checkDesiredVersion checks if the desired version is available.
100
+ checkDesiredVersion () {
101
+ if [ " x$DESIRED_VERSION " == " x" ]; then
102
+ # Get tag from release URL
103
+ local latest_release_url=" https://api.github.com/repos/kagent-dev/kagent/releases/latest"
104
+ local latest_release_response=" "
105
+ if [ " ${HAS_CURL} " == " true" ]; then
106
+ latest_release_response=$( curl --header " Authorization: Bearer $GITHUB_TOKEN " -L --silent --show-error --fail " $latest_release_url " 2>&1 || true )
107
+ elif [ " ${HAS_WGET} " == " true" ]; then
108
+ latest_release_response=$( wget " $latest_release_url " -q -O - 2>&1 || true )
109
+ fi
110
+ TAG=$( echo " $latest_release_response " | jq -r .tag_name | grep ' ^v[0-9]' )
111
+ if [ " x$TAG " == " x" ]; then
112
+ printf " Could not retrieve the latest release tag information from %s: %s\n" " ${latest_release_url} " " ${latest_release_response} "
113
+ exit 1
114
+ fi
115
+ else
116
+ TAG=$DESIRED_VERSION
117
+ fi
118
+ }
119
+
120
+ # checkKagentInstalledVersion checks which version of is installed and
121
+ # if it needs to be changed.
122
+ checkKagentInstalledVersion () {
123
+ if [[ -f " ${KAGENT_INSTALL_DIR} /${BINARY_NAME} " ]]; then
124
+ local version=$( " ${KAGENT_INSTALL_DIR} /${BINARY_NAME} " version --template=" {{ .Version }}" )
125
+ if [[ " $version " == " $TAG " ]]; then
126
+ echo " kagent ${version} is already ${DESIRED_VERSION:- latest} "
127
+ return 0
128
+ else
129
+ echo " kagent ${TAG} is available. Changing from version ${version} ."
130
+ return 1
131
+ fi
132
+ else
133
+ return 1
134
+ fi
135
+ }
136
+
137
+ # downloadFile downloads the latest binary package and also the checksum
138
+ # for that binary.
139
+ downloadFile () {
140
+ KAGENT_DIST=" kagent-$OS -$ARCH "
141
+ DOWNLOAD_URL=" https://github.com/kagent-dev/kagent/releases/download/$TAG /$KAGENT_DIST "
142
+ CHECKSUM_URL=" $DOWNLOAD_URL .sha256"
143
+ KAGENT_TMP_ROOT=" $( mktemp -dt kagent -installer-XXXXXX) "
144
+ KAGENT_TMP_FILE=" $KAGENT_TMP_ROOT /$KAGENT_DIST "
145
+ KAGENT_SUM_FILE=" $KAGENT_TMP_ROOT /$KAGENT_DIST .sha256"
146
+ echo " Downloading $DOWNLOAD_URL "
147
+ if [ " ${HAS_CURL} " == " true" ]; then
148
+ curl --header " Authorization: Bearer $GITHUB_TOKEN " -SsL " $CHECKSUM_URL " -o " $KAGENT_SUM_FILE "
149
+ curl --header " Authorization: Bearer $GITHUB_TOKEN " -SsL " $DOWNLOAD_URL " -o " $KAGENT_TMP_FILE "
150
+ elif [ " ${HAS_WGET} " == " true" ]; then
151
+ wget -q -O " $KAGENT_SUM_FILE " " $CHECKSUM_URL "
152
+ wget -q -O " $KAGENT_TMP_FILE " " $DOWNLOAD_URL "
153
+ fi
154
+ }
155
+
156
+ # verifyFile verifies the SHA256 checksum of the binary package
157
+ # and the GPG signatures for both the package and checksum file
158
+ # (depending on settings in environment).
159
+ verifyFile () {
160
+ if [ " ${VERIFY_CHECKSUM} " == " true" ]; then
161
+ verifyChecksum
162
+ fi
163
+ }
164
+
165
+ # installFile installs the kagent binary.
166
+ installFile () {
167
+ KAGENT_TMP=" $KAGENT_TMP_ROOT /$BINARY_NAME "
168
+ mkdir -p " $KAGENT_TMP "
169
+ tar xf " $KAGENT_TMP_FILE " -C " $KAGENT_TMP "
170
+ KAGENT_TMP_BIN=" $KAGENT_TMP /$OS -$ARCH /kagent"
171
+ echo " Preparing to install $BINARY_NAME into ${KAGENT_INSTALL_DIR} "
172
+ runAsRoot cp " $KAGENT_TMP_BIN " " $KAGENT_INSTALL_DIR /$BINARY_NAME "
173
+ echo " $BINARY_NAME installed into $KAGENT_INSTALL_DIR /$BINARY_NAME "
174
+ }
175
+
176
+ # verifyChecksum verifies the SHA256 checksum of the binary package.
177
+ verifyChecksum () {
178
+ printf " Verifying checksum... "
179
+ local sum=$( openssl sha1 -sha256 ${KAGENT_TMP_FILE} | awk ' {print $2}' )
180
+ local expected_sum=$( cat ${KAGENT_SUM_FILE} )
181
+ if [ " $sum " != " $expected_sum " ]; then
182
+ echo " SHA sum of ${KAGENT_TMP_FILE} does not match. Aborting."
183
+ exit 1
184
+ fi
185
+ echo " Done."
186
+ }
187
+
188
+ # fail_trap is executed if an error occurs.
189
+ fail_trap () {
190
+ result=$?
191
+ if [ " $result " != " 0" ]; then
192
+ if [[ -n " $INPUT_ARGUMENTS " ]]; then
193
+ echo " Failed to install $BINARY_NAME with the arguments provided: $INPUT_ARGUMENTS "
194
+ help
195
+ else
196
+ echo " Failed to install $BINARY_NAME "
197
+ fi
198
+ echo -e " \tFor support, go to https://github.com/kagent-dev/kagent."
199
+ fi
200
+ cleanup
201
+ exit $result
202
+ }
203
+
204
+ # testVersion tests the installed client to make sure it is working.
205
+ testVersion () {
206
+ set +e
207
+ KAGENT=" $( command -v $BINARY_NAME ) "
208
+ if [ " $? " = " 1" ]; then
209
+ echo " $BINARY_NAME not found. Is $KAGENT_INSTALL_DIR on your " ' $PATH?'
210
+ exit 1
211
+ fi
212
+ set -e
213
+ }
214
+
215
+ # help provides possible cli installation arguments
216
+ help () {
217
+ echo " Accepted cli arguments are:"
218
+ echo -e " \t[--help|-h ] ->> prints this help"
219
+ echo -e " \t[--version|-v <desired_version>] . When not defined it fetches the latest release tag from the kagent GitHub repository"
220
+ echo -e " \te.g. --version v3.0.0 or -v canary"
221
+ echo -e " \t[--no-sudo] ->> install without sudo"
222
+ }
223
+
224
+ # cleanup temporary files to avoid https://github.com/helm/helm/issues/2977
225
+ cleanup () {
226
+ if [[ -d " ${KAGENT_TMP_ROOT:- } " ]]; then
227
+ rm -rf " $KAGENT_TMP_ROOT "
228
+ fi
229
+ }
230
+
231
+ # Execution
232
+
233
+ # Stop execution on any error
234
+ trap " fail_trap" EXIT
235
+ set -e
236
+
237
+ # Set debug if desired
238
+ if [ " ${DEBUG} " == " true" ]; then
239
+ set -x
240
+ fi
241
+
242
+ # Parsing input arguments (if any)
243
+ export INPUT_ARGUMENTS=" ${@ } "
244
+ set -u
245
+ while [[ $# -gt 0 ]]; do
246
+ case $1 in
247
+ ' --version' |-v)
248
+ shift
249
+ if [[ $# -ne 0 ]]; then
250
+ export DESIRED_VERSION=" ${1} "
251
+ if [[ " $1 " != " v" * ]]; then
252
+ echo " Expected version arg ('${DESIRED_VERSION} ') to begin with 'v', fixing..."
253
+ export DESIRED_VERSION=" v${1} "
254
+ fi
255
+ else
256
+ echo -e " Please provide the desired version. e.g. --version v0.1.0 or -v canary"
257
+ exit 0
258
+ fi
259
+ ;;
260
+ ' --no-sudo' )
261
+ USE_SUDO=" false"
262
+ ;;
263
+ ' --help' |-h)
264
+ help
265
+ exit 0
266
+ ;;
267
+ * ) exit 1
268
+ ;;
269
+ esac
270
+ shift
271
+ done
272
+ set +u
273
+
274
+ initArch
275
+ initOS
276
+ verifySupported
277
+ checkDesiredVersion
278
+ if ! checkKagentInstalledVersion; then
279
+ downloadFile
280
+ verifyFile
281
+ installFile
282
+ fi
283
+ testVersion
284
+ cleanup
0 commit comments