aboutsummaryrefslogtreecommitdiffstats
path: root/bin/pacman-offline
blob: a6e2a99ada8f18d4d9aa369f13e73cd9db605c2f (plain) (blame)
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
#!/bin/sh

# (C) 2017-2024 by Christian Hesse <mail@eworm.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

set -e

function help() {
	echo "usage: ${0} [OPTIONS]"
	echo
	echo ' -c  clean before download'
	echo ' -f  force if other system-update is pending'
	echo ' -h  this help'
	echo ' -p  reboot, install and poweroff immediately'
	echo ' -r  reboot and install immediately'
	echo ' -t  start timer for nightly reboot'
	echo ' -y  update sync databases'
}

CLEAN=0
POWEROFF=0
REBOOT=0
TIMER=0

while getopts 'cfhprty' opt; do
	case ${opt} in
		h)
			help
			exit 0
			;;
	esac
done

if [ "${UID}" -ne 0 ]; then
	if command -v run0 >/dev/null; then
		echo 'Missing privileges, trying to elevate.' >&2
		exec run0 "${0}" "${@}"
	fi

	echo "You need elevated privileges. Please run as user 'root'!" >&2
	exit 1
fi

OPTIND=1
while getopts 'cfhprty' opt; do
	case ${opt} in
		c)
			if pacman-conf 'CleanMethod' | grep -q 'KeepCurrent'; then
				CLEAN=1
			else
				echo 'The clean method is not set to keep current. Not cleaning.' >&2
			fi
			;;
		f)
			rm -f /system-update
			;;
		p)
			POWEROFF=1
			REBOOT=1
			;;
		r)
			REBOOT=1
			;;
		t)
			TIMER=1
			;;
		y)
			pacman --sync --refresh
			;;
	esac
done

# make sure no other update is pending
if [ -e '/system-update' -a "$(readlink '/system-update')" != '/var/cache/pacman/pkg' ]; then
	echo 'Another update is pending.' >&2
	exit 1
fi

# exclude /etc/pacman.d/offline.conf
function finish { rm -f /run/pacman.conf; }
trap finish EXIT
sed '/^Include *= *\/etc\/pacman\.d\/offline\.conf$/s|^|#|' < /etc/pacman.conf > /run/pacman.conf

# remove the symlink for now, will be recreated it later
rm -f /system-update

# check for available updates
if [ "$(pacman --config /run/pacman.conf --sync --sysupgrade --print | wc -l)" -eq 0 ]; then
	echo "No updates available."
	exit 0
fi

# clean cache
if [ ${CLEAN} -eq 1 ]; then
	pacman --sync --noconfirm --clean
fi

# download packages
pacman --config /run/pacman.conf --sync --noconfirm --sysupgrade --downloadonly

# enable system update
ln -sf /var/cache/pacman/pkg /system-update
if [ ${POWEROFF} -eq 1 ]; then
	touch /run/system-update-poweroff
fi

# (soft-)reboot if requested
if [ ${REBOOT} -eq 1 ]; then
	echo "Soft-rebooting for update."
	systemctl soft-reboot
else
	# force a soft-reboot on (manual) reboot ...
	ln -sf ../../../usr/lib/systemd/system/systemd-soft-reboot.service /run/systemd/system/systemd-reboot.service

	# ... and also on poweroff, but prepare poweroff
	cp /usr/lib/systemd/system/systemd-soft-reboot.service /run/systemd/system/systemd-poweroff.service 
	cat >> /run/systemd/system/systemd-poweroff.service <<-EOF

	[Service]
	ExecStart=/usr/bin/touch /run/system-update-poweroff
	EOF

	systemctl daemon-reload
fi

# start timer if requested
if [ ${TIMER} -eq 1 ]; then
	systemctl start pacman-offline-reboot.timer
fi

# show the timer (if active)
systemctl --quiet --no-pager list-timers pacman-offline-prepare.timer pacman-offline-reboot.timer