summaryrefslogtreecommitdiff
blob: 6dcaf1de23db4bcacde5824ab43750b45a2a7116 (plain)
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
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/eclass/check-reqs.eclass,v 1.4 2005/07/06 20:23:20 agriffis Exp $
#
# Original Author: Ciaran McCreesh <ciaranm@gentoo.org>
#
# This eclass provides a uniform way of handling ebuilds which have very high
# build requirements in terms of memory or disc space. It provides a function
# which should usually be called during pkg_setup().
#
# From a user perspective, the variable CHECKREQS_ACTION can be set to:
#    * "warn" (default), which will display a warning and wait for 15s
#    * "error", which will make the ebuild error out
#    * "ignore", which will not take any action
# The chosen action only happens when the system's resources are detected
# correctly and only if they are below the threshold specified by the package.
#
# For ebuild authors: only use this eclass if you reaaalllllly have stupidly
# high build requirements. At an absolute minimum, you shouldn't be using this
# unless the ebuild needs >256MBytes RAM or >1GByte temporary or install space.
# The code should look something like:
#
# pkg_setup() {
#     # values in MBytes
#
#     # need this much memory (does *not* check swap)
#     CHECKREQS_MEMORY="256"
#
#     # need this much temporary build space
#     CHECKREQS_DISK_BUILD="2048"
#
#     # install will need this much space in /usr
#     CHECKREQS_DISK_USR="1024"
#
#     # install will need this much space in /var
#     CHECKREQS_DISK_VAR="1024"
#
#     # go!
#     check_reqs
# }
#
# You should *not* override the user's CHECKREQS_ACTION setting, nor should you
# attempt to provide a value if it is unset. Note that the environment variables
# are used rather than parameters for a few reasons:
#   * easier to do if use blah ; then things
#   * we might add in additional requirements things later
# If you don't specify a value for, say, CHECKREQS_MEMORY, then the test is not
# carried out.
#
# These checks should probably mostly work on non-Linux, and they should
# probably degrade gracefully if they don't. Probably.

inherit eutils


check_reqs() {
	[ -n "$1" ] && die "Usage: check_reqs"

	export CHECKREQS_NEED_SLEEP="" CHECKREQS_NEED_DIE=""
	if [ "$CHECKREQS_ACTION" != "ignore" ] ; then
		[ -n "$CHECKREQS_MEMORY" ] && check_build_memory
		[ -n "$CHECKREQS_DISK_BUILD" ] && check_build_disk \
			"${PORTAGE_TMPDIR}" "\${PORTAGE_TMPDIR}" "${CHECKREQS_DISK_BUILD}"
		[ -n "$CHECKREQS_DISK_USR" ] && check_build_disk \
			"${ROOT}/usr"  "\${ROOT}/usr" "${CHECKREQS_DISK_USR}"
		[ -n "$CHECKREQS_DISK_VAR" ] && check_build_disk \
			"${ROOT}/var"  "\${ROOT}/var" "${CHECKREQS_DISK_VAR}"
	fi

	if [ -n "${CHECKREQS_NEED_SLEEP}" ] ; then
		echo
		ewarn "Bad things may happen! You may abort the build by pressing ctrl+c in"
		ewarn "the next 15 seconds."
		ewarn " "
		einfo "To make this kind of warning a fatal error, add a line to /etc/make.conf"
		einfo "setting CHECKREQS_ACTION=\"error\". To skip build requirements checking,"
		einfo "set CHECKREQS_ACTION=\"ignore\"."
		epause 15
	fi

	if [ -n "${CHECKREQS_NEED_DIE}" ] ; then
		eerror "Bailing out as specified by CHECKREQS_ACTION"
		die "Build requirements not met"
	fi
}

# internal use only!
check_build_memory() {
	[ -n "$1" ] && die "Usage: check_build_memory"
	check_build_msg_begin "${CHECKREQS_MEMORY}" "MBytes" "RAM"
	if [ -r /proc/meminfo ] ; then
		actual_memory=$(sed -n -e '/MemTotal:/s/^[^:]*: *\([0-9]\+\) kB/\1/p' \
			/proc/meminfo)
	else
		actual_memory=$(sysctl hw.physmem 2>/dev/null )
		[ "$?" == "0" ] &&
			actual_memory=$(echo $actual_memory | sed -e 's/^[^:=]*[:=]//' )
	fi
	if [ -n "${actual_memory}" ] ; then
		if [ ${actual_memory} -lt $((1024 * ${CHECKREQS_MEMORY})) ] ; then
			eend 1
			check_build_msg_ick "${CHECKREQS_MEMORY}" "MBytes" "RAM"
		else
			eend 0
		fi
	else
		eend 1
		ewarn "Couldn't determine amount of memory, skipping ..."
	fi
}

# internal use only!
check_build_disk() {
	[ -z "$3" ] && die "Usage: check_build_disk where name needed"
	check_build_msg_begin "${3}" "MBytes" \
			"disk space at ${2}"
	actual_space=$(df -Pm ${1} 2>/dev/null | sed -n \
			'$s/\(\S\+\s\+\)\{3\}\([0-9]\+\).*/\2/p' 2>/dev/null )
	if [ "$?" == "0" ] && [ -n "${actual_space}" ] ; then
		if [ ${actual_space} -lt ${3} ] ; then
			eend 1
			check_build_msg_ick "${3}" "MBytes" \
					"disk space at ${2}"
		else
			eend 0
		fi
	else
		eend 1
		ewarn "Couldn't figure out disk space, skipping ..."
	fi
}

# internal use only!
check_build_msg_begin() {
	ebegin "Checking for at least ${1}${2} ${3}"
}

# internal use only!
check_build_msg_skip() {
	ewarn "Skipping check for at least ${1}${2} ${3}"
}

# internal use only!
check_build_msg_ick() {
	if [ "${CHECKREQS_ACTION}" == "error" ] ; then
		eerror "Don't have at least ${1}${2} ${3}"
		echo
		export CHECKREQS_NEED_DIE="yes"
	else
		ewarn "Don't have at least ${1}${2} ${3}"
		echo
		export CHECKREQS_NEED_SLEEP="yes"
	fi
}