/[gentoo-x86]/eclass/check-reqs.eclass
Gentoo

Diff of /eclass/check-reqs.eclass

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.5 Revision 1.12
1# Copyright 1999-2004 Gentoo Foundation 1# Copyright 1999-2012 Gentoo Foundation
2# Distributed under the terms of the GNU General Public License v2 2# Distributed under the terms of the GNU General Public License v2
3# $Header: /var/cvsroot/gentoo-x86/eclass/check-reqs.eclass,v 1.5 2006/02/15 12:51:25 ciaranm Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/check-reqs.eclass,v 1.12 2012/10/19 02:44:21 patrick Exp $
4# 4
5# @ECLASS: check-reqs.eclass
6# @MAINTAINER:
7# QA Team <qa@gentoo.org>
8# @AUTHOR:
9# Bo ├śrsted Andresen <zlin@gentoo.org>
5# Original Author: Ciaran McCreesh <ciaranm@gentoo.org> 10# Original Author: Ciaran McCreesh <ciaranm@gentoo.org>
6# 11# @BLURB: Provides a uniform way of handling ebuild which have very high build requirements
12# @DESCRIPTION:
7# This eclass provides a uniform way of handling ebuilds which have very high 13# This eclass provides a uniform way of handling ebuilds which have very high
8# build requirements in terms of memory or disc space. It provides a function 14# build requirements in terms of memory or disk space. It provides a function
9# which should usually be called during pkg_setup(). 15# which should usually be called during pkg_setup().
10# 16#
11# From a user perspective, the variable CHECKREQS_ACTION can be set to:
12# * "warn" (default), which will display a warning and wait for 15s
13# * "error", which will make the ebuild error out
14# * "ignore", which will not take any action
15# The chosen action only happens when the system's resources are detected 17# The chosen action only happens when the system's resources are detected
16# correctly and only if they are below the threshold specified by the package. 18# correctly and only if they are below the threshold specified by the package.
17# 19#
18# For ebuild authors: only use this eclass if you reaaalllllly have stupidly 20# @CODE
19# high build requirements. At an absolute minimum, you shouldn't be using this
20# unless the ebuild needs >256MBytes RAM or >1GByte temporary or install space.
21# The code should look something like:
22#
23# pkg_setup() {
24# # values in MBytes
25#
26# # need this much memory (does *not* check swap) 21# # need this much memory (does *not* check swap)
27# CHECKREQS_MEMORY="256" 22# CHECKREQS_MEMORY="256M"
28# 23#
29# # need this much temporary build space 24# # need this much temporary build space
30# CHECKREQS_DISK_BUILD="2048" 25# CHECKREQS_DISK_BUILD="2G"
31# 26#
32# # install will need this much space in /usr 27# # install will need this much space in /usr
33# CHECKREQS_DISK_USR="1024" 28# CHECKREQS_DISK_USR="1G"
34# 29#
35# # install will need this much space in /var 30# # install will need this much space in /var
36# CHECKREQS_DISK_VAR="1024" 31# CHECKREQS_DISK_VAR="1024M"
37# 32#
38# # go! 33# @CODE
39# check_reqs
40# }
41# 34#
42# Alternatively, the check_reqs_conditional function can be used to carry out
43# alternate actions (e.g. using a much slower but far less memory intensive
44# build option that gives the same end result).
45#
46# You should *not* override the user's CHECKREQS_ACTION setting, nor should you
47# attempt to provide a value if it is unset. Note that the environment variables
48# are used rather than parameters for a few reasons:
49# * easier to do if use blah ; then things
50# * we might add in additional requirements things later
51# If you don't specify a value for, say, CHECKREQS_MEMORY, then the test is not 35# If you don't specify a value for, say, CHECKREQS_MEMORY, then the test is not
52# carried out. 36# carried out.
53# 37#
54# These checks should probably mostly work on non-Linux, and they should 38# These checks should probably mostly work on non-Linux, and they should
55# probably degrade gracefully if they don't. Probably. 39# probably degrade gracefully if they don't. Probably.
56 40
57inherit eutils 41inherit eutils
58 42
43# @ECLASS-VARIABLE: CHECKREQS_MEMORY
44# @DEFAULT_UNSET
45# @DESCRIPTION:
46# How much RAM is needed? Eg.: CHECKREQS_MEMORY=15M
59 47
48# @ECLASS-VARIABLE: CHECKREQS_DISK_BUILD
49# @DEFAULT_UNSET
50# @DESCRIPTION:
51# How much diskspace is needed to build the package? Eg.: CHECKREQS_DISK_BUILD=2T
52
53# @ECLASS-VARIABLE: CHECKREQS_DISK_USR
54# @DEFAULT_UNSET
55# @DESCRIPTION:
56# How much space in /usr is needed to install the package? Eg.: CHECKREQS_DISK_USR=15G
57
58# @ECLASS-VARIABLE: CHECKREQS_DISK_VAR
59# @DEFAULT_UNSET
60# @DESCRIPTION:
61# How much space is needed in /var? Eg.: CHECKREQS_DISK_VAR=3000M
62
63EXPORT_FUNCTIONS pkg_setup
64case "${EAPI:-0}" in
65 0|1|2|3) ;;
66 4|5) EXPORT_FUNCTIONS pkg_pretend ;;
67 *) die "EAPI=${EAPI} is not supported" ;;
68esac
69
70# @FUNCTION: check_reqs
71# @DESCRIPTION:
72# Obsolete function executing all the checks and priting out results
60check_reqs() { 73check_reqs() {
61 [ -n "$1" ] && die "Usage: check_reqs" 74 debug-print-function ${FUNCNAME} "$@"
62 75
63 export CHECKREQS_NEED_SLEEP="" CHECKREQS_NEED_DIE=""
64 if [ "$CHECKREQS_ACTION" != "ignore" ] ; then
65 [ -n "$CHECKREQS_MEMORY" ] && check_build_memory
66 [ -n "$CHECKREQS_DISK_BUILD" ] && check_build_disk \
67 "${PORTAGE_TMPDIR}" "\${PORTAGE_TMPDIR}" "${CHECKREQS_DISK_BUILD}"
68 [ -n "$CHECKREQS_DISK_USR" ] && check_build_disk \
69 "${ROOT}/usr" "\${ROOT}/usr" "${CHECKREQS_DISK_USR}"
70 [ -n "$CHECKREQS_DISK_VAR" ] && check_build_disk \
71 "${ROOT}/var" "\${ROOT}/var" "${CHECKREQS_DISK_VAR}"
72 fi
73
74 if [ -n "${CHECKREQS_NEED_SLEEP}" ] ; then
75 echo 76 echo
76 ewarn "Bad things may happen! You may abort the build by pressing ctrl+c in" 77 ewarn "QA: Package calling old ${FUNCNAME} function."
77 ewarn "the next 15 seconds." 78 ewarn "QA: Please file a bug against the package."
78 ewarn " " 79 ewarn "QA: It should call check-reqs_pkg_pretend and check-reqs_pkg_setup"
79 einfo "To make this kind of warning a fatal error, add a line to /etc/make.conf" 80 ewarn "QA: and possibly use EAPI=4 or later."
80 einfo "setting CHECKREQS_ACTION=\"error\". To skip build requirements checking," 81 echo
81 einfo "set CHECKREQS_ACTION=\"ignore\"."
82 epause 15
83 fi
84 82
83 check-reqs_pkg_setup "$@"
84}
85
86# @FUNCTION: check-reqs_pkg_setup
87# @DESCRIPTION:
88# Exported function running the resources checks in pkg_setup phase.
89# It should be run in both phases to ensure condition changes between
90# pkg_pretend and pkg_setup won't affect the build.
91check-reqs_pkg_setup() {
92 debug-print-function ${FUNCNAME} "$@"
93
94 [[ ${MERGE_TYPE} == binary ]] && return
95
96 check-reqs_prepare
97 check-reqs_run
98 check-reqs_output
99}
100
101# @FUNCTION: check-reqs_pkg_pretend
102# @DESCRIPTION:
103# Exported function running the resources checks in pkg_pretend phase.
104check-reqs_pkg_pretend() {
105 debug-print-function ${FUNCNAME} "$@"
106
107 check-reqs_pkg_setup "$@"
108}
109
110# @FUNCTION: check-reqs_prepare
111# @DESCRIPTION:
112# Internal function that checks the variables that should be defined.
113check-reqs_prepare() {
114 debug-print-function ${FUNCNAME} "$@"
115
116 if [[ -z ${CHECKREQS_MEMORY} &&
117 -z ${CHECKREQS_DISK_BUILD} &&
118 -z ${CHECKREQS_DISK_USR} &&
119 -z ${CHECKREQS_DISK_VAR} ]]; then
120 eerror "Set some check-reqs eclass variables if you want to use it."
121 eerror "If you are user and see this message file a bug against the package."
122 die "${FUNCNAME}: check-reqs eclass called but not actualy used!"
123 fi
124}
125
126# @FUNCTION: check-reqs_run
127# @DESCRIPTION:
128# Internal function that runs the check based on variable settings.
129check-reqs_run() {
130 debug-print-function ${FUNCNAME} "$@"
131
132 # some people are *censored*
133 unset CHECKREQS_FAILED
134
135 [[ -n ${CHECKREQS_MEMORY} ]] && \
136 check-reqs_memory \
137 ${CHECKREQS_MEMORY}
138
139 [[ -n ${CHECKREQS_DISK_BUILD} ]] && \
140 check-reqs_disk \
141 "${T}" \
142 "${CHECKREQS_DISK_BUILD}"
143
144 [[ -n ${CHECKREQS_DISK_USR} ]] && \
145 check-reqs_disk \
146 "${EROOT}/usr" \
147 "${CHECKREQS_DISK_USR}"
148
149 [[ -n ${CHECKREQS_DISK_VAR} ]] && \
150 check-reqs_disk \
151 "${EROOT}/var" \
152 "${CHECKREQS_DISK_VAR}"
153}
154
155# @FUNCTION: check-reqs_get_mebibytes
156# @DESCRIPTION:
157# Internal function that returns number in mebibytes.
158# Converts from 1G=1024 or 1T=1048576
159check-reqs_get_mebibytes() {
160 debug-print-function ${FUNCNAME} "$@"
161
162 [[ -z ${1} ]] && die "Usage: ${FUNCNAME} [size]"
163
164 local unit=${1:(-1)}
165 local size=${1%[GMT]}
166
167 case ${unit} in
168 G) echo $((1024 * size)) ;;
169 [M0-9]) echo ${size} ;;
170 T) echo $((1024 * 1024 * size)) ;;
171 *)
172 die "${FUNCNAME}: Unknown unit: ${unit}"
173 ;;
174 esac
175}
176
177# @FUNCTION: check-reqs_get_number
178# @DESCRIPTION:
179# Internal function that returns number without the unit.
180# Converts from 1G=1 or 150T=150.
181check-reqs_get_number() {
182 debug-print-function ${FUNCNAME} "$@"
183
184 [[ -z ${1} ]] && die "Usage: ${FUNCNAME} [size]"
185
186 local unit=${1:(-1)}
187 local size=${1%[GMT]}
188
189 # Check for unset units and warn about them.
190 # Backcompat.
191 if [[ ${size} == ${1} ]]; then
192 ewarn "QA: Package does not specify unit for the size check"
193 ewarn "QA: Assuming mebibytes."
194 ewarn "QA: File bug against the package. It should specify the unit."
195 fi
196
197 echo ${size}
198}
199
200# @FUNCTION: check-reqs_get_unit
201# @DESCRIPTION:
202# Internal function that returns number without the unit.
203# Converts from 1G=1 or 150T=150.
204check-reqs_get_unit() {
205 debug-print-function ${FUNCNAME} "$@"
206
207 [[ -z ${1} ]] && die "Usage: ${FUNCNAME} [size]"
208
209 local unit=${1:(-1)}
210
211 case ${unit} in
212 G) echo "gibibytes" ;;
213 [M0-9]) echo "mebibytes" ;;
214 T) echo "tebibytes" ;;
215 *)
216 die "${FUNCNAME}: Unknown unit: ${unit}"
217 ;;
218 esac
219}
220
221# @FUNCTION: check-reqs_output
222# @DESCRIPTION:
223# Internal function that prints the warning and dies if required based on
224# the test results.
225check-reqs_output() {
226 debug-print-function ${FUNCNAME} "$@"
227
228 local msg="ewarn"
229
230 [[ ${EBUILD_PHASE} == "pretend" && -z ${I_KNOW_WHAT_I_AM_DOING} ]] && msg="eerror"
85 if [ -n "${CHECKREQS_NEED_DIE}" ] ; then 231 if [[ -n ${CHECKREQS_FAILED} ]]; then
86 eerror "Bailing out as specified by CHECKREQS_ACTION" 232 ${msg}
233 ${msg} "Space constrains set in the ebuild were not met!"
234 ${msg} "The build will most probably fail, you should enhance the space"
235 ${msg} "as per failed tests."
236 ${msg}
237
238 [[ ${EBUILD_PHASE} == "pretend" && -z ${I_KNOW_WHAT_I_AM_DOING} ]] && \
87 die "Build requirements not met" 239 die "Build requirements not met!"
88 fi 240 fi
89} 241}
90 242
91check_reqs_conditional() { 243# @FUNCTION: check-reqs_memory
92 [ -n "$1" ] && die "Usage: check_reqs" 244# @DESCRIPTION:
245# Internal function that checks size of RAM.
246check-reqs_memory() {
247 debug-print-function ${FUNCNAME} "$@"
93 248
94 export CHECKREQS_NEED_SLEEP="" CHECKREQS_NEED_DIE="" 249 [[ -z ${1} ]] && die "Usage: ${FUNCNAME} [size]"
95 if [ "$CHECKREQS_ACTION" != "ignore" ] ; then
96 [ -n "$CHECKREQS_MEMORY" ] && check_build_memory
97 [ -n "$CHECKREQS_DISK_BUILD" ] && check_build_disk \
98 "${PORTAGE_TMPDIR}" "\${PORTAGE_TMPDIR}" "${CHECKREQS_DISK_BUILD}"
99 [ -n "$CHECKREQS_DISK_USR" ] && check_build_disk \
100 "${ROOT}/usr" "\${ROOT}/usr" "${CHECKREQS_DISK_USR}"
101 [ -n "$CHECKREQS_DISK_VAR" ] && check_build_disk \
102 "${ROOT}/var" "\${ROOT}/var" "${CHECKREQS_DISK_VAR}"
103 fi
104 250
105 [ -z "${CHECKREQS_NEED_SLEEP}" ] && [ -z "${CHECKREQS_NEED_DIE}" ] 251 local size=${1}
106} 252 local actual_memory
107 253
108# internal use only! 254 check-reqs_start_phase \
109check_build_memory() { 255 ${size} \
110 [ -n "$1" ] && die "Usage: check_build_memory" 256 "RAM"
111 check_build_msg_begin "${CHECKREQS_MEMORY}" "MBytes" "RAM" 257
112 if [ -r /proc/meminfo ] ; then 258 if [[ -r /proc/meminfo ]] ; then
113 actual_memory=$(sed -n -e '/MemTotal:/s/^[^:]*: *\([0-9]\+\) kB/\1/p' \ 259 actual_memory=$(awk '/MemTotal/ { print $2 }' /proc/meminfo)
114 /proc/meminfo)
115 else 260 else
116 actual_memory=$(sysctl hw.physmem 2>/dev/null ) 261 actual_memory=$(sysctl hw.physmem 2>/dev/null )
117 [ "$?" == "0" ] && 262 [[ "$?" == "0" ]] &&
118 actual_memory=$(echo $actual_memory | sed -e 's/^[^:=]*[:=]//' ) 263 actual_memory=$(echo $actual_memory | sed -e 's/^[^:=]*[:=]//' )
119 fi 264 fi
120 if [ -n "${actual_memory}" ] ; then 265 if [[ -n ${actual_memory} ]] ; then
121 if [ ${actual_memory} -lt $((1024 * ${CHECKREQS_MEMORY})) ] ; then 266 if [[ ${actual_memory} -lt $((1024 * $(check-reqs_get_mebibytes ${size}))) ]] ; then
122 eend 1 267 eend 1
123 check_build_msg_ick "${CHECKREQS_MEMORY}" "MBytes" "RAM" 268 check-reqs_unsatisfied \
269 ${size} \
270 "RAM"
124 else 271 else
125 eend 0 272 eend 0
126 fi 273 fi
127 else 274 else
128 eend 1 275 eend 1
129 ewarn "Couldn't determine amount of memory, skipping ..." 276 ewarn "Couldn't determine amount of memory, skipping..."
130 fi 277 fi
131} 278}
132 279
133# internal use only! 280# @FUNCTION: check-reqs_disk
134check_build_disk() { 281# @DESCRIPTION:
135 [ -z "$3" ] && die "Usage: check_build_disk where name needed" 282# Internal function that checks space on the harddrive.
136 check_build_msg_begin "${3}" "MBytes" \ 283check-reqs_disk() {
284 debug-print-function ${FUNCNAME} "$@"
285
286 [[ -z ${2} ]] && die "Usage: ${FUNCNAME} [path] [size]"
287
288 local path=${1}
289 local size=${2}
290 local space_megs
291
292 check-reqs_start_phase \
293 ${size} \
137 "disk space at ${2}" 294 "disk space at \"${path}\""
138 actual_space=$(df -Pm ${1} 2>/dev/null | sed -n \ 295
139 '$s/\(\S\+\s\+\)\{3\}\([0-9]\+\).*/\2/p' 2>/dev/null ) 296 space_megs=$(df -Pm "${1}" 2>/dev/null | awk 'FNR == 2 {print $4}')
140 if [ "$?" == "0" ] && [ -n "${actual_space}" ] ; then 297
141 if [ ${actual_space} -lt ${3} ] ; then 298 if [[ $? == 0 && -n ${space_megs} ]] ; then
299 if [[ ${space_megs} -lt $(check-reqs_get_mebibytes ${size}) ]] ; then
142 eend 1 300 eend 1
143 check_build_msg_ick "${3}" "MBytes" \ 301 check-reqs_unsatisfied \
302 ${size} \
144 "disk space at ${2}" 303 "disk space at \"${path}\""
145 else 304 else
146 eend 0 305 eend 0
147 fi 306 fi
148 else 307 else
149 eend 1 308 eend 1
150 ewarn "Couldn't figure out disk space, skipping ..." 309 ewarn "Couldn't determine disk space, skipping..."
151 fi 310 fi
152} 311}
153 312
154# internal use only! 313# @FUNCTION: check-reqs_start_phase
155check_build_msg_begin() { 314# @DESCRIPTION:
315# Internal function that inform about started check
316check-reqs_start_phase() {
317 debug-print-function ${FUNCNAME} "$@"
318
319 [[ -z ${2} ]] && die "Usage: ${FUNCNAME} [size] [location]"
320
321 local size=${1}
322 local location=${2}
323 local sizeunit="$(check-reqs_get_number ${size}) $(check-reqs_get_unit ${size})"
324
156 ebegin "Checking for at least ${1}${2} ${3}" 325 ebegin "Checking for at least ${sizeunit} ${location}"
157} 326}
158 327
159# internal use only! 328# @FUNCTION: check-reqs_unsatisfied
160check_build_msg_skip() { 329# @DESCRIPTION:
161 ewarn "Skipping check for at least ${1}${2} ${3}" 330# Internal function that inform about check result.
162} 331# It has different output between pretend and setup phase,
332# where in pretend phase it is fatal.
333check-reqs_unsatisfied() {
334 debug-print-function ${FUNCNAME} "$@"
163 335
164# internal use only! 336 [[ -z ${2} ]] && die "Usage: ${FUNCNAME} [size] [location]"
165check_build_msg_ick() {
166 if [ "${CHECKREQS_ACTION}" == "error" ] ; then
167 eerror "Don't have at least ${1}${2} ${3}"
168 echo
169 export CHECKREQS_NEED_DIE="yes"
170 else
171 ewarn "Don't have at least ${1}${2} ${3}"
172 echo
173 export CHECKREQS_NEED_SLEEP="yes"
174 fi
175}
176 337
338 local msg="ewarn"
339 local size=${1}
340 local location=${2}
341 local sizeunit="$(check-reqs_get_number ${size}) $(check-reqs_get_unit ${size})"
342
343 [[ ${EBUILD_PHASE} == "pretend" && -z ${I_KNOW_WHAT_I_AM_DOING} ]] && msg="eerror"
344 ${msg} "There is NOT at least ${sizeunit} ${location}"
345
346 # @ECLASS-VARIABLE: CHECKREQS_FAILED
347 # @DESCRIPTION:
348 # @INTERNAL
349 # If set the checks failed and eclass should abort the build.
350 # Internal, do not set yourself.
351 CHECKREQS_FAILED="true"
352}
353

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.12

  ViewVC Help
Powered by ViewVC 1.1.20