setup-apkcache.in 3.12 KB
Newer Older
1 2 3 4 5 6 7
#!/bin/sh

PREFIX=

. "$PREFIX/lib/libalpine.sh"

usage() {
8 9
	cat <<-__EOF__
		usage: setup-apkcache [-h] [DIR]
10

11
		Setup apk caching.
12

13
		If DIR is not specified user will be asked for location.
14

15 16 17
		options:
		 -h  Show this help
	__EOF__
18
	exit 1
19 20 21 22 23 24
}

is_mounted() {
	awk '{print $2}' /proc/mounts | grep -q "^$1$"
}

25 26 27
find_fstab_mount_point() {
	local dir="$1"
	local res=
28 29 30
	if ! [ -r "${ROOT}"etc/fstab ]; then
		return
	fi
31
	while [ -n "$dir" ]; do
32
		res=$(awk "\$2 == \"$dir\" {print \$2}" "${ROOT}"etc/fstab)
33 34 35 36 37 38 39 40
		if [ -n "$res" ]; then
			echo $res
			return
		fi
		dir=${dir%/*}
	done
}

41 42
# figure out mount point
find_mount_point() {
43 44 45 46 47 48
	local dir=$(find_fstab_mount_point $1)
	if [ -d "$dir" ] && [ "$dir" != "/" ]; then
		echo $dir
		return
	fi

49
	local dir="$1"
50
	while [ -n "$dir" ] && ! [ -d "$dir" ]; do
51 52
		dir=${dir%/*}
	done
53
	local fs_id=$(stat -f -c %i "${dir:-/}")
54
	local parent="${dir%/*}"
55
	while [ -n "$dir" ] && [ "$(stat -f -c %i $parent/)" = "$fs_id" ]; do
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
		dir=$parent
		parent=${parent%/*}
	done
	[ -z "$dir" ] && dir=/
	echo $dir
}

get_mount_opts() {
	local mnt="$1"
	awk "\$2 == \"$mnt\" {gsub(/,/, \" \", \$4); print \$4}" /proc/mounts
}

is_mounted_ro() {
	local mnt="$1"
	local opts=$(get_mount_opts $mnt)
	local opt=
	for opt in $opts; do
		if [ "$opt" = "ro" ]; then
			return 0
		fi
	done
	return 1
}

80 81 82 83 84 85 86
# get the fstype of the given mount point
mount_fstype() {
	# we only want the last mount in case there are several
	awk -v mnt="$1" '$2 == "/" {fstype = mnt} END {print fstype}' \
		/proc/mounts
}

87
apk_cache_help() {
88
	cat <<-__EOF__
89

90 91 92
		Packages installed from network can be cached locally to be available during
		boot, before the network is started. Specifying a directory here will make apk
		cache the packages locally in this directory.
93

94
		Enter 'none' if you do not want to cache packages from network.
95

96
	__EOF__
97 98
}

99
while getopts "h" opt; do
100
	case $opt in
101
		h) usage;;
102
	esac
103 104 105 106 107
done
shift $(( $OPTIND - 1 ))

# try auto detetect what we suggest
suggestion=
108 109
if [ -L "${ROOT}"etc/apk/cache ]; then
	suggestion=$(readlink "${ROOT}"etc/apk/cache)
Natanael Copa's avatar
Natanael Copa committed
110
fi
111

112 113
if [ -z "$suggestion" ] && [ -f "${ROOT}"etc/lbu/lbu.conf ]; then
	. "${ROOT}"etc/lbu/lbu.conf
114 115 116 117 118 119 120 121 122
	if [ -n "$LBU_MEDIA" ]; then
		suggestion=/media/$LBU_MEDIA/cache
	fi
fi

if [ -z "$suggestion" ] && [ -L /dev/usbdisk ]; then
	suggestion=/media/usb/cache
fi

123 124 125 126
if [ -z "$suggestion" ] && [ "$(mount_fstype /)" != "tmpfs" ]; then
	suggestion=/var/cache/apk
fi

127 128 129 130 131 132
if [ -z "$suggestion" ]; then
	suggestion=none
fi
cachedir=$1

while [ -z "$cachedir" ]; do
133
	echo -n "Enter apk cache directory (or '?' or 'none') [$suggestion]: "
134
	default_read cachedir $suggestion
135 136 137 138
	if [ "$cachedir" = "?" ]; then
		apk_cache_help
		cachedir=
	fi
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
done

if [ "$cachedir" = "none" ]; then
	exit 0
fi

mount=$(find_mount_point $cachedir)

cleanup=

if ! is_mounted $mount; then
	mount $mount || exit 1
	cleanup="umount"
elif is_mounted_ro $mount; then
	mount -o remount,rw $mount || exit 1
	cleanup="remount"
fi

mkdir -p $cachedir
158 159
if [ -L "${ROOT}"etc/apk/cache ]; then
	rm -f "${ROOT}"etc/apk/cache
160
fi
161 162
mkdir -p "${ROOT}"etc/apk
ln -s $cachedir "${ROOT}"etc/apk/cache
163 164 165 166 167

case "$cleanup" in
	umount) umount $mount;;
	remount) mount -o remount,ro $mount;;
esac