File: lib.sh

package info (click to toggle)
libiio 0.26-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,832 kB
  • sloc: ansic: 21,880; python: 1,844; cs: 1,232; sh: 1,062; cpp: 688; yacc: 441; xml: 192; lex: 172; makefile: 40
file content (562 lines) | stat: -rw-r--r-- 13,721 bytes parent folder | download | duplicates (2)
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
#!/bin/sh -e

if [ "$TRIGGER_NEXT_BUILD" = "true" ] && [ "$TRIGGERING_NEXT_BUILD" != "true" ] ; then
	exit 0
fi

export TRAVIS_API_URL="https://api.travis-ci.com"
LOCAL_BUILD_DIR=${LOCAL_BUILD_DIR:-build}

HOMEBREW_NO_INSTALL_CLEANUP=1
export HOMEBREW_NO_INSTALL_CLEANUP

PYTHON=python3
export PYTHON

# This needs to be duplicated inside 'inside_docker.sh'
# It's the common convention between host & container
INSIDE_DOCKER_BUILD_DIR=/docker_build_dir

# Add here all the common env-vars that should be propagated
# to the docker image, simply by referencing the env-var name.
# The values will be evaluated.
#
# Make sure to not pass certain stuff that are specific to the host
# and not specific to inside-the-docker (like TRAVIS_BUILD_DIR)
#
# If these nothing should be passed, then clear or
#'unset INSIDE_DOCKER_TRAVIS_CI_ENV' after this script is included
INSIDE_DOCKER_TRAVIS_CI_ENV="TRAVIS TRAVIS_COMMIT TRAVIS_PULL_REQUEST OS_TYPE OS_VERSION ARTIFACTNAME"

COMMON_SCRIPTS="inside_docker.sh"

echo_red()   { printf "\033[1;31m$*\033[m\n"; }
echo_green() { printf "\033[1;32m$*\033[m\n"; }
echo_blue()  { printf "\033[1;34m$*\033[m\n"; }

backtrace() {
	# shell backtraces only work on bash
	if [ ! -z "${BASH}" ] ; then
		local i=
		i=${#FUNCNAME[@]}
		((--i))

		while (( i >= 0 ))
		do
			echo "${BASH_SOURCE[$i]}:${BASH_LINENO[$i]}.${FUNCNAME[$i]}()"
			i=$((i - 1))
		done
	fi
}

get_script_path() {
	local script="$1"

	[ -n "$script" ] || return 1

	if [ -f "CI/travis/$script" ] ; then
		echo "CI/travis/$script"
	elif [ -f "ci/travis/$script" ] ; then
		echo "ci/travis/$script"
	elif [ -f "${LOCAL_BUILD_DIR}/$script" ] ; then
		echo "${LOCAL_BUILD_DIR}/$script"
	else
		return 1
	fi
}

pipeline_branch() {
	local branch=$1

	[ -n "$branch" ] || return 1

	# master is a always a pipeline branch
	[ "$branch" = "master" ] && return 0

	set +x
	# Check if branch name is 20XX_RY where:
	#   XX - 14 to 99 /* wooh, that's a lot of years */
	#   Y  - 1 to 9   /* wooh, that's a lot of releases per year */
	for year in $(seq 2014 2099) ; do
		for rel_num in $(seq 1 9) ; do
			[ "$branch" = "${year}_R${rel_num}" ] && \
				return 0
		done
	done

	return 1
}

should_trigger_next_builds() {
	local branch="$1"

	[ -z "${COVERITY_SCAN_PROJECT_NAME}" ] || return 1

	# These Travis-CI vars have to be non-empty
	[ -n "$TRAVIS_PULL_REQUEST" ] || return 1
	[ -n "$branch" ] || return 1
	set +x
	[ -n "$TRAVIS_API_TOKEN" ] || return 1

	# Has to be a non-pull-request
	[ "$TRAVIS_PULL_REQUEST" = "false" ] || return 1

	pipeline_branch "$branch" || return 1
}

trigger_build() {
	local repo_slug="$1"
	local branch="$2"

	[ -n "$repo_slug" ] || return 1
	[ -n "$branch" ] || return 1

	local body="{
		\"request\": {
			\"branch\":\"$branch\"
		}
	}"

	# Turn off tracing here (shortly)
	set +x
	curl -s -X POST \
		-H "Content-Type: application/json" \
		-H "Accept: application/json" \
		-H "Travis-API-Version: 3" \
		-H "Authorization: token $TRAVIS_API_TOKEN" \
		-d "$body" \
		"${TRAVIS_API_URL}/repo/$repo_slug/requests"
}

trigger_adi_build() {
	local adi_repo="$1"
	local branch="$2"

	[ -n "$adi_repo" ] || return 1
	trigger_build "analogdevicesinc%2F$adi_repo" "$branch"
}

command_exists() {
	local cmd=$1
	[ -n "$cmd" ] || return 1
	type "$cmd" >/dev/null 2>&1
}

get_ldist() {
	case "$(uname)" in
	Linux*)
		if [ ! -f /etc/os-release ] ; then
			if [ -f /etc/centos-release ] ; then
				echo "centos-$(sed -e 's/CentOS release //' -e 's/(.*)$//' \
					-e 's/ //g' /etc/centos-release)-$(uname -m)"
				return 0
			fi
			ls /etc/*elease
			[ -z "${OSTYPE}" ] || {
				echo "${OSTYPE}-unknown"
				return 0
			}
			echo "linux-unknown"
			return 0
		fi
		. /etc/os-release
		if ! command_exists dpkg ; then
			echo $ID-$VERSION_ID-$(uname -m)
		else
			echo $ID-$VERSION_ID-$(dpkg --print-architecture)
		fi
		;;
	Darwin*)
		echo "darwin-$(sw_vers -productVersion)"
		;;
	*)
		echo "$(uname)-unknown"
		;;
	esac
	return 0
}

__brew_install_or_upgrade() {
	brew install "$1" || \
		brew upgrade "$1" || \
		brew ls --versions "$1"
}

brew_install_or_upgrade() {
	while [ -n "$1" ] ; do
		__brew_install_or_upgrade "$1" || return 1
		shift
	done
}

__brew_install_if_not_exists() {
	brew ls --versions "$1" || \
		brew install "$1"
}

brew_install_if_not_exists() {
	while [ -n "$1" ] ; do
		__brew_install_if_not_exists "$1" || return 1
		shift
	done
}

sftp_cmd_pipe() {
	sftp -o "StrictHostKeyChecking no" "${EXTRA_SSH}" "${SSHUSER}@${SSHHOST}"
}

sftp_run_cmds() {
	local x=5
	while [ "${x}" -gt "0" ] ; do
		sftp -o "StrictHostKeyChecking no" "${EXTRA_SSH}" "${SSHUSER}@${SSHHOST}" 0< "$1" && break;
		echo_red "failed to ssh, trying again"
		x=$((x  - 1))
		sleep 10
	done
	if [ "${x}" -eq "0" ] ; then
		echo_red "failed to upload files"
		return 1;
	fi
	return 0
}

sftp_rm_artifact() {
	local artifact="$1"
	sftp_cmd_pipe <<-EOF
		cd ${DEPLOY_TO}
		rm ${artifact}
		bye
	EOF
}

sftp_upload() {
	local FROM="$1"
	local TO="$2"
	local LATE="$3"

	if [ -n "${LATE}" ] ; then
		sftp_cmd_pipe <<-EOF
			cd ${DEPLOY_TO}
			put ${FROM} ${TO}
			ls -l ${TO}
			symlink ${TO} ${LATE}
			ls -l ${LATE}
			bye
		EOF
	else
		sftp_cmd_pipe <<-EOF
			cd ${DEPLOY_TO}
			put ${FROM} ${TO}
			ls -l ${TO}
			bye
		EOF
	fi
}

upload_file_to_swdownloads() {

	if [ "$#" -ne 4 ] ; then
		echo "skipping deployment of something"
		echo "send called with $@"
		return 0
	fi

	local LIBNAME=$1
	local FROM=$2
	local FNAME=$3
	local EXT=$4

	if [ -z "$FROM" ] ; then
		echo no file to send
		return 1
	fi

	if [ ! -r "$FROM" ] ; then
		echo "file $FROM is not readable"
		return 1
	fi

	if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] ; then
		local branch="$TRAVIS_PULL_REQUEST_BRANCH"
	else
		local branch="$TRAVIS_BRANCH"
	fi

	local TO=${branch}_${FNAME}
	local LATE=${branch}_latest_${LIBNAME}${LDIST}${EXT}
	local GLOB=${DEPLOY_TO}/${branch}_${LIBNAME}-*

	echo attempting to deploy "$FROM" to "$TO"
	echo and "${branch}_${LIBNAME}${LDIST}${EXT}"
	ssh -V

	local tmpfl=$(mktemp)
	echo "cd ${DEPLOY_TO}" > "${tmpfl}"
	echo "rm ${TO}" >> "${tmpfl}"
	echo "rm ${LATE}" >> "${tmpfl}"
	echo "put ${FROM} ${TO}" >> "${tmpfl}"
	echo "symlink ${TO} ${LATE}" >> "${tmpfl}"
	echo "ls -l ${TO}" >> "${tmpfl}"
	echo "ls -l ${LATE}" >> "${tmpfl}"
	echo "bye"  >> "${tmpfl}"

	sftp_run_cmds "${tmpfl}"
	rm "${tmpfl}"

	return 0
}

remove_old_pkgs() {
	# limit things to a few files, so things don't grow forever
	# we only do this on one build so simultaneous builds don't clobber each other
	if [ -z "${GH_DOC_TOKEN}" ] ; then
		return 0
	fi

	if [ -z "${TRAVIS_BUILD_DIR}" ] ; then
		echo "TRAVIS_BUILD_DIR not set"
		return 0
	fi

	if [ ! -d "${TRAVIS_BUILD_DIR}/.git" ] ; then
		echo "No ${TRAVIS_BUILD_DIR}/.git to operate git on"
		return 0
	fi

	local LIBNAME=$1
	local old=

	echo "Remove old packages from ${LIBNAME}"

	if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] ; then
		local branch="$TRAVIS_PULL_REQUEST_BRANCH"
	else
		local branch="$TRAVIS_BRANCH"
	fi

	local GLOB=${DEPLOY_TO}/${branch}_${LIBNAME}-*

	# putting everything into a file, and connecting once decreases the chances
	# for ssh issues, connections happen once, not every single file
	local tmpfl=$(mktemp)
	echo "cd ${DEPLOY_TO}" > "${tmpfl}"
	for files in $(ssh -o "StrictHostKeyChecking no" "${EXTRA_SSH}" "${SSHUSER}@${SSHHOST}" \
			"ls -lt ${GLOB}" | tail -n +100 | awk '{print $NF}')
	do
		echo "rm ${files}" >> "${tmpfl}"
	done
	echo "bye" >> "${tmpfl}"
	# if it is only cd & bye, skip it
	if [ "$(wc -l "${tmpfl}" | awk '{print $1}')" -gt "2" ] ; then
		sftp_run_cmds "${tmpfl}"
	fi
	rm "${tmpfl}"
	# provide an index so people can find files.
	ssh -o "StrictHostKeyChecking no" "${EXTRA_SSH}" "${SSHUSER}@${SSHHOST}" \
			"ls -lt ${DEPLOY_TO}" | grep "${LIBNAME}" > "${LIBNAME}_index.html"
	echo "ls captured"

	echo "cd ${DEPLOY_TO}" > "${tmpfl}"
	# prune old / removed branches, leave things are are tags/branches
	for old in $(sed 's/-> .*$//' libiio_index.html | \
			awk  '{print $NF}' | grep -v master | sort | \
			sed "s/_libiio-0.[0-9][0-9].g[a-z0-9]*-/ %% /" | \
			grep "%%" | awk '{print $1}' | sort -u)
	do
		if [ "$(git --git-dir "${TRAVIS_BUILD_DIR}/.git" ls-remote --heads origin "${old}" | wc -l)" -ne "0" ] ; then
			echo "${old} is a branch"
		else
			if [ "$(git --git-dir "${TRAVIS_BUILD_DIR}/.git" ls-remote --tags origin "${old}" | wc -l)" -ne "0" ] ; then
				echo "${old} is a tag"
			else
				echo "${old} can be removed"
				echo "rm ${old}_${LIBNAME}-*" >> "${tmpfl}"
				echo "rm ${old}_latest_${LIBNAME}-*" >> "${tmpfl}"
				echo "rm ${old}_lastest_${LIBNAME}-*" >> "${tmpfl}"
			fi
		fi
	done
	# cap things at 15, so we don't exceed the time
	sed -i 16q "${tmpfl}"
	echo "bye" >> "${tmpfl}"
	# if it is only cd & bye, skip it
	if [ "$(wc -l "${tmpfl}" | awk '{print $1}')" -gt "2" ] ; then
		sftp_run_cmds "${tmpfl}"
	fi
	rm "${tmpfl}"

	#Now that we removed things, do it again
	rm "${LIBNAME}_index.html"
	ssh -o "StrictHostKeyChecking no" "${EXTRA_SSH}" "${SSHUSER}@${SSHHOST}" \
			"ls -lt ${DEPLOY_TO}" | grep "${LIBNAME}" > "${LIBNAME}_index.html"
	sftp_upload "${LIBNAME}_index.html" "${LIBNAME}_index.html"

	return 0
}

prepare_docker_image() {
	local DOCKER_IMAGE="${OS_TYPE}:${OS_VERSION}"
	# If arch is specified, setup multiarch support
	if [ -n "$OS_ARCH" ] ; then
		sudo apt-get -qq update
		sudo DEBIAN_FRONTEND=noninteractive apt-get install -y qemu \
			qemu binfmt-support qemu-user-static
		sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
		DOCKER_IMAGE="${OS_ARCH}/${DOCKER_IMAGE}"
	fi
	echo 'DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock -s devicemapper"' | sudo tee /etc/default/docker > /dev/null
	sudo service docker restart
	sudo docker pull "$DOCKER_IMAGE"
}

__save_env_for_docker() {
	local env_file="$1/inside-travis-ci-docker-env"
	for env in $INSIDE_DOCKER_TRAVIS_CI_ENV ; do
		val="$(eval echo "\$${env}")"
		if [ -n "$val" ] ; then
			echo "export ${env}=\"${val}\"" >> "${env_file}"
		fi
	done
}

run_docker_script() {
	local DOCKER_SCRIPT="$(get_script_path "$1")"
	local MOUNTPOINT="${INSIDE_DOCKER_BUILD_DIR}"
	local DOCKER_IMAGE="${OS_TYPE}:${OS_VERSION}"

	if [ -n "$OS_ARCH" ] ; then
		DOCKER_IMAGE="${OS_ARCH}/${DOCKER_IMAGE}"
	fi

	__save_env_for_docker "$(pwd)"

	sudo docker run --rm=true \
		-v "$(pwd):/${MOUNTPOINT}:rw" \
		"$DOCKER_IMAGE" \
		/bin/bash -e "/${MOUNTPOINT}/${DOCKER_SCRIPT}" "${MOUNTPOINT}" "${OS_TYPE}"
}

ensure_command_exists() {
	local cmd="$1"
	local package="$2"
	local yes_confirm
	[ -n "$cmd" ] || return 1
	[ -n "$package" ] || package="$cmd"
	! command_exists "$cmd" || return 0
	# go through known package managers
	for pacman in apt-get brew yum ; do
		command_exists $pacman || continue
		if [ "$pacman" = "brew" ] ; then
			yes_confirm=
		else
			yes_confirm="-y"
		fi
		"$pacman" install $yes_confirm "$package" || {
			# Try an update if install doesn't work the first time
			"$pacman" $yes_confirm update && \
				"$pacman" install $yes_confirm "$package"
		}
		return $?
	done
	return 1
}

version_gt() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"; }
version_le() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" = "$1"; }
version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; }
version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" = "$1"; }

get_codename() {
	local VERSION_CODENAME
	eval $(grep -w VERSION_CODENAME /etc/os-release)
	echo "$VERSION_CODENAME"
}

get_dist_id() {
	local ID
	eval $(grep -w ID /etc/os-release)
	echo "$ID"
}

get_version() {
	local VERSION_ID
	eval $(grep -w VERSION_ID /etc/os-release)
	echo "$VERSION_ID"
}

is_ubuntu_at_least_ver() {
	[ "$(get_dist_id)" = "ubuntu" ] || return 1
	version_ge "$(get_version)" "$1"
}

is_centos_at_least_ver() {
	[ "$(get_dist_id)" = "centos" ] || return 1
	version_ge "$(get_version)" "$1"
}

is_python_at_least_ver() {
	local out python_exec

	python_exec="$1"
	command_exists "$python_exec" || return 1
	out=$($python_exec --version)
	version_ge "${out#* }" "$2"
}

is_arm() {
	[ "$(dpkg --print-architecture)" = "armhf" ] || return 1
}

is_arm64() {
	[ "$(dpkg --print-architecture)" = "arm64" ] || return 1
}

print_github_api_rate_limits() {
	# See https://developer.github.com/v3/rate_limit/
	# Note: Accessing this endpoint does not count against your REST API rate limit.
	echo_green '-----------------------------------------'
	echo_green 'Github API Rate limits'
	echo_green '-----------------------------------------'
	wget -q -O- https://api.github.com/rate_limit
	echo_green '-----------------------------------------'
}

setup_build_type_env_vars() {
	OS_TYPE=${OS_TYPE:-default}

	# For a 'arm32_v7/debian_docker' string, OS TYPE becomes 'debian'
	# This also works for just 'debian_docker'
	# And we're extracting OS_ARCH if present
	if [ "${OS_TYPE#*_}" = "docker" ] ; then
		BUILD_TYPE=generic_docker
		OS_TYPE=${OS_TYPE%_*}
		OS_ARCH=${OS_TYPE%/*}
		OS_TYPE=${OS_TYPE#*/}
		if [ "$OS_ARCH" = "$OS_TYPE" ] ; then
			OS_ARCH=
		fi
	else
		BUILD_TYPE="$OS_TYPE"
	fi

	export OS_TYPE
	export OS_ARCH
	export BUILD_TYPE
}

ensure_command_exists sudo
ensure_command_exists wget

# Other scripts will download lib.sh [this script] and lib.sh will
# in turn download the other scripts it needs.
# This gives way more flexibility when changing things, as they propagate
for script in $COMMON_SCRIPTS ; do
	[ ! -f "CI/travis/$script" ] || continue
	[ ! -f "ci/travis/$script" ] || continue
	[ ! -f "${LOCAL_BUILD_DIR}/$script" ] || continue
	mkdir -p "${LOCAL_BUILD_DIR}"
	wget https://raw.githubusercontent.com/analogdevicesinc/libiio/master/CI/travis/$script \
		-O "$LOCAL_BUILD_DIR/$script"
done

print_github_api_rate_limits