Repository navigation
Expand file tree
/
Copy pathbuild.sh
More file actions
executable file
·168 lines (134 loc) · 4.09 KB
/
Copy pathbuild.sh
File metadata and controls
executable file
·168 lines (134 loc) · 4.09 KB
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
#!/bin/bash
set -o errexit
files_url='https://files.balena-cloud.com' # URL exporting S3 XML
s3_xml=$(curl -L -s $files_url)
# From https://stackoverflow.com/a/7052168
read_dom () {
local IFS=\>
read -d \< ENTITY CONTENT
}
s3_bucket=$(while read_dom; do if [[ $ENTITY = "Name" ]] ; then echo $CONTENT; fi; done <<<"$s3_xml")
# Output arguments to stderr.
function err()
{
echo "$@">&2
}
# Output arguments to stderr and halt with non-zero exit code.
function fatal()
{
err "$@"
exit 1
}
# Output usage and halt.
function usage()
{
err "usage: $0 <device type> <version> <module path>"
fatal " or: $0 --list - list available devices and versions"
}
function push()
{
pushd $1 >/dev/null
}
function pop()
{
popd >/dev/null
}
# Retrieves all available kernel header archives.
# args: $1 - device search pattern (default .*)
# $2 - version search pattern (default .*)
function get_header_paths()
{
local dev_pat="${1:-.*}"
local ver_pat="${2:-.*}"
list_kernels=$(aws s3api list-objects --no-sign-request --bucket $s3_bucket --output text --query 'Contents[]|[?contains(Key, `kernel`)]' | cut -f2)
while read -r line; do
if echo "$line" | grep -q "images/$dev_pat/$ver_pat"; then
device=$(echo "$line" | cut -f2 -d/)
version=$(echo "$line" | cut -f3 -d/)
echo "$line"
fi
done <<< "$list_kernels"
}
# List available devices and versions.
function list_versions()
{
list_kernels=$(aws s3api list-objects --no-sign-request --bucket $s3_bucket --output text --query 'Contents[]|[?contains(Key, `kernel`)]|[?contains(Key,`images`)]' | cut -f2)
while read -r line; do
var1=$(echo "$line" | cut -f1 -d/)
device=$(echo "$line" | cut -f2 -d/)
version=$(echo "$line" | cut -f3 -d/)
printf "%-30s %-30s\n" "$device" "$version"
done <<< "$list_kernels"
}
# Retrieve kernel module headers from the specified remote path and build kernel
# module against them, generating a new copy of the kernel module with
# ..._<device>_<version> suffix.
function get_and_build()
{
local path="$1"
local pattern="^images/(.*)/(.*)/"
[[ "$path" =~ $pattern ]] || fatal "Invalid path '$path'?!"
local device="${BASH_REMATCH[1]}"
local version="${BASH_REMATCH[2]}"
local output_dir="${module_dir}_${device}_${version}"
filename=$(basename $path)
url="$files_url/$path"
tmp_path=$(mktemp --directory)
push $tmp_path
if ! wget $(echo "$url" | sed -e 's/+/%2B/g'); then
pop
rm -rf "$tmp_path"
err "ERROR: $path: Could not retrieve $url, skipping."
return
fi
strip_depth=1
if [[ $filename == *"source"* ]]; then
# The kernel source tarball has a leading ./ as well. Increase strip_depth
strip_depth=2
# Change output_dir to avoid overwriting the modules compiled from just the headers tarball
output_dir="${output_dir}_from_src"
fi
if ! tar -xf $filename --strip $strip_depth; then
pop
rm -rf "$tmp_path"
err "ERROR: $path: Unable to extract $tmp_path/$filename, skipping."
return
fi
# Kernel headers for some devices need a few workarounds to build. These workarounds either effect
# the build environment. Or the headers were incorrectly generated during the os build stage.
# The full kernel source tarball available from v2.30+ should always work.
/usr/src/app/workarounds.sh $device $version $output_dir
# Check if we have fetched the kernel_source tarball
if [[ $filename == *"source"* ]]; then
# Prepare tools
make -C "$tmp_path" modules_prepare
fi
pop
# Now create a copy of the module directory.
rm -rf "$output_dir"
mkdir "$output_dir"
cp -R "$module_dir"/* "$output_dir"
push "$output_dir"
make -C "$tmp_path" M="$PWD" modules
pop
rm -rf "$tmp_path"
}
if [[ "$1" = "--list" ]]; then
echo "Fetching list from servers"
list_versions
exit
elif [[ $# -lt 3 ]]; then
usage
fi
device="$1"
version="$2"
module_dir="$3"
[[ -d "$module_dir" ]] || fatal "ERROR: Cannot find module directory $module_dir"
seen=''
echo "Fetching list from servers"
for path in $(get_header_paths "$device" "$version"); do
echo "Building $path..."
get_and_build $path
seen='y'
done
[[ -n "$seen" ]] || fatal "Could not find headers for '$device' at version '$version', run $0 --list"