common 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. #!/bin/bash
  2. # Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. BUILD_SYSTEM="libreboot"
  17. PROJECTS="projects"
  18. SOURCES="sources"
  19. BUILD="build"
  20. INSTALL="install"
  21. RELEASE="release"
  22. SYSTEMS="systems"
  23. IMAGES="images"
  24. TOOLS="tools"
  25. CONFIGS="configs"
  26. PATCHES="patches"
  27. TARGETS="targets"
  28. REVISION="revision"
  29. BLOBS="blobs"
  30. BLOBS_IGNORE="blobs-ignore"
  31. BLOBS_DISCOVER="blobs-discover"
  32. DOTEPOCH=".epoch"
  33. DOTVERSION=".version"
  34. DOTREVISION=".revision"
  35. DOTTARFILES=".tarfiles"
  36. TAR_XZ="tar.xz"
  37. SHA256SUM="sha256sum"
  38. ASC="asc"
  39. function_check() {
  40. local function=$1
  41. declare -f -F "$function" > /dev/null
  42. }
  43. variable_check() {
  44. local variable=$1
  45. test ! -z "${!variable}"
  46. }
  47. arguments_list() {
  48. local argument
  49. for argument in "$@"
  50. do
  51. echo "$argument"
  52. done
  53. }
  54. diff_patch_file() {
  55. local repository_path="$1"
  56. local patch_file_path="$2"
  57. local filename_in_diff="$(sed -rne 's/^-{3} {1}(.*)$/\1/p' <"${patch_file_path}")"
  58. local source_file_path
  59. if ! ( grep -E '^-{3}.*/' <"${patch_file_path}" >/dev/null 2>&1 ); then
  60. source_file_path="${repository_path}/${filename_in_diff##\ }"
  61. else
  62. source_file_path="${repository_path}/${filename_in_diff##*/}"
  63. fi
  64. patch "${source_file_path}" "${patch_file_path}"
  65. }
  66. path_wildcard_expand() {
  67. local path=$@
  68. # Evaluation fails with unescaped whitespaces.
  69. path=$( echo "$path" | sed "s/ /\\\ /g" )
  70. eval "arguments_list "$path""
  71. }
  72. file_checksum_create() {
  73. local path=$1
  74. local checksum_path="$path.$SHA256SUM"
  75. local name=$( basename "$path" )
  76. local directory_path=$( dirname "$path" )
  77. (
  78. cd "$directory_path"
  79. sha256sum "$name" > "$checksum_path"
  80. )
  81. }
  82. file_checksum_check() {
  83. local path=$1
  84. local checksum_path="$path.$SHA256SUM"
  85. local name=$( basename "$path" )
  86. local directory_path=$( dirname "$path" )
  87. if ! [ -f "$checksum_path" ]
  88. then
  89. printf "Could not verify file checksum!\n" >&2
  90. return 1
  91. fi
  92. (
  93. cd "$directory_path"
  94. sha256sum -c "$checksum_path"
  95. )
  96. }
  97. file_signature_create() {
  98. local path=$1
  99. local signature_path="$path.$ASC"
  100. if [ -z "$RELEASE_KEY" ]
  101. then
  102. return 0
  103. fi
  104. gpg --default-key "$RELEASE_KEY" --armor --output "$signature_path" --detach-sign --yes "$path"
  105. }
  106. file_signature_check() {
  107. local path=$1
  108. local signature_path="$path.$ASC"
  109. if ! [ -f "$signature_path" ]
  110. then
  111. printf "Could not verify file signature!\n" >&2
  112. return 1
  113. fi
  114. gpg --armor --verify "$signature_path" "$path"
  115. }
  116. file_verification_create() {
  117. local path=$1
  118. file_checksum_create "$path"
  119. file_signature_create "$path"
  120. }
  121. file_verification_check() {
  122. local path=$1
  123. file_checksum_check "$path"
  124. file_signature_check "$path"
  125. }
  126. file_exists_check() {
  127. local path=$1
  128. test -f "$path"
  129. }
  130. directory_filled_check() {
  131. local path=$1
  132. if [ -z "$( ls -A "$path" 2> /dev/null )" ]
  133. then
  134. return 1
  135. else
  136. return 0
  137. fi
  138. }
  139. archive_files_create() {
  140. local source_path=$1
  141. local directory=$( basename "$source_path" )
  142. local tarfiles_path="$source_path/$DOTTARFILES"
  143. local revision_path="$source_path/$DOTREVISION"
  144. local version_path="$source_path/$DOTVERSION"
  145. if git_check "$source_path"
  146. then
  147. git_files "$source_path" | tr -d '\0' > "$tarfiles_path"
  148. echo "$DOTTARFILES" | tr -d '\0' >> "$tarfiles_path"
  149. else
  150. touch "$tarfiles_path"
  151. (
  152. cd "$source_path"
  153. find
  154. ) | LC_ALL=C sort | sed "s,^./,," | grep -vP "^\.$" > "$tarfiles_path"
  155. fi
  156. if [ -f "$revision_path" ]
  157. then
  158. echo "$DOTREVISION" | tr -d '\0' >> "$tarfiles_path"
  159. fi
  160. if [ -f "$version_path" ]
  161. then
  162. echo "$DOTVERSION" | tr -d '\0' >> "$tarfiles_path"
  163. fi
  164. if [ -f "$epoch_path" ]
  165. then
  166. echo "$DOTEPOCH" | tr -d '\0' >> "$tarfiles_path"
  167. fi
  168. }
  169. archive_files_date() {
  170. local source_path=$1
  171. local epoch_path="$source_path/$DOTEPOCH"
  172. if ! [ -z "$SOURCE_DATE_EPOCH" ]
  173. then
  174. (
  175. cd "$source_path"
  176. find -exec touch --no-dereference --date="@$SOURCE_DATE_EPOCH" {} \;
  177. )
  178. fi
  179. }
  180. archive_create() {
  181. local archive_path=$1
  182. local source_path=$2
  183. local directory=$3
  184. local tarfiles_path="$source_path/$DOTTARFILES"
  185. local directory_path=$( dirname "$archive_path" )
  186. mkdir -p "$directory_path"
  187. if [ -z "$directory" ]
  188. then
  189. directory=$( basename "$source_path" )
  190. fi
  191. archive_files_create "$source_path"
  192. archive_files_date "$source_path"
  193. (
  194. cd "$source_path"
  195. tar -cJf "$archive_path" --no-recursion -T "$tarfiles_path" --transform="s,^,$directory/,S" --owner=root --group=root --numeric-owner
  196. )
  197. }
  198. archive_extract() {
  199. local archive_path=$1
  200. local destination_path=$2
  201. if [ -z "$destination_path" ]
  202. then
  203. destination_path=$( dirname "$archive_path" )
  204. fi
  205. tar -xf "$archive_path" -ps -C "$destination_path"
  206. }
  207. rootfs_files_create() {
  208. local source_path=$1
  209. local directory=$( basename "$source_path" )
  210. local tarfiles_path="$source_path/$DOTTARFILES"
  211. touch "$tarfiles_path"
  212. (
  213. cd "$source_path"
  214. execute_root find
  215. ) | LC_ALL=C sort | sed "s,^./,," | grep -vP "^$DOTTARFILES|^\.$" > "$tarfiles_path"
  216. }
  217. rootfs_files_date() {
  218. local source_path=$1
  219. local epoch_path="$source_path/$DOTEPOCH"
  220. if ! [ -z "$SOURCE_DATE_EPOCH" ]
  221. then
  222. (
  223. cd "$source_path"
  224. execute_root find -exec touch --no-dereference --date="@$SOURCE_DATE_EPOCH" {} \;
  225. )
  226. fi
  227. }
  228. rootfs_create() {
  229. local rootfs_path=$1
  230. local source_path=$2
  231. local directory=$3
  232. local tarfiles_path="$source_path/$DOTTARFILES"
  233. local directory_path=$( dirname "$rootfs_path" )
  234. mkdir -p "$directory_path"
  235. if [ -z "$directory" ]
  236. then
  237. directory=$( basename "$source_path" )
  238. fi
  239. rootfs_files_create "$source_path"
  240. rootfs_files_date "$source_path"
  241. (
  242. cd "$source_path"
  243. execute_root tar -cJf "$rootfs_path" --no-recursion -T "$tarfiles_path" --numeric-owner
  244. )
  245. execute_root chmod 644 "$rootfs_path"
  246. execute_root chown $USER:$USER "$rootfs_path"
  247. }
  248. requirements() {
  249. local requirement
  250. local requirement_path
  251. for requirement in "$@"
  252. do
  253. requirement_path=$( which "$requirement" || true )
  254. if [ -z "$requirement_path" ]
  255. then
  256. printf "Missing requirement: $requirement\n" >&2
  257. exit 1
  258. fi
  259. done
  260. }
  261. requirements_root() {
  262. local requirement
  263. local requirement_path
  264. for requirement in "$@"
  265. do
  266. # We need to keep stdout output to show the command.
  267. requirement_path=$( execute_root which "$requirement" || true )
  268. if [ -z "$requirement_path" ]
  269. then
  270. printf "Missing requirement: $requirement\n" >&2
  271. exit 1
  272. fi
  273. done
  274. }
  275. arguments_concat() {
  276. local delimiter=$1
  277. shift
  278. local concat
  279. for argument in "$@"
  280. do
  281. if ! [ -z "$concat" ]
  282. then
  283. concat="$concat""$delimiter""$argument"
  284. else
  285. concat="$argument"
  286. fi
  287. done
  288. echo "$concat"
  289. }
  290. execute_root() {
  291. local sudo=$( which sudo 2> /dev/null || true )
  292. local arguments
  293. printf "Running command as root: " >&2
  294. echo "$@" >&2
  295. if ! [ -z "$sudo" ]
  296. then
  297. sudo "$@"
  298. else
  299. # Quote arguments for eval through su.
  300. arguments=$( printf "%q " "$@" )
  301. su -c "$arguments"
  302. fi
  303. }