summarylogtreecommitdiffstats
path: root/PKGBUILD.install
blob: 230794eda2aa0ff999355908335f655d3137eff6 (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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
#!/bin/bash
qubes_preset_file="75-qubes-vm.preset"

###########################
## Pre-Install functions ##
###########################

update_default_user() {
    # Make sure there is a qubes group
    groupadd --force --system --gid 98 qubes

    # Archlinux bash version has a 'bug' when running su -c, /etc/profile is not loaded because bash consider there is no interactive pty when running 'su - user -c' or something like this.
    # See https://bugs.archlinux.org/task/31831
    id -u 'user' >/dev/null 2>&1 || {
        useradd --user-group --create-home --shell /bin/bash user
    }
    usermod -a --groups qubes user
}

## arg 1:  the new package version
pre_install() {
    echo "Pre install..."

    update_default_user

    # do this whole %pre thing only when updating for the first time...

    mkdir -p /var/lib/qubes

    # Backup fstab / But use archlinux defaults (cp instead of mv)
    if [ -e /etc/fstab ] ; then
        cp /etc/fstab /var/lib/qubes/fstab.orig
    fi

    # Add qubes core related fstab entries
    echo "xen	/proc/xen	xenfs	defaults	0 0" >> /etc/fstab

    usermod -L root
    usermod -L user
}


## arg 1:  the new package version
## arg 2:  the old package version
pre_upgrade() {
    # do something here
    echo "Pre upgrade..."

    update_default_user
}

###################
## Install Hooks ##
###################


configure_notification-daemon() {
    # Enable autostart of notification-daemon when installed
    if [ ! -L /etc/xdg/autostart/notification-daemon.desktop ]; then
        ln -s /usr/share/applications/notification-daemon.desktop /etc/xdg/autostart/
    fi
}

configure_selinux() {
    # SELinux is not enabled on archlinux
    #echo "--> Disabling SELinux..."
    echo "SELINUX not enabled on archlinux. skipped."
    # sed -e s/^SELINUX=.*$/SELINUX=disabled/ -i /etc/selinux/config
    # setenforce 0 2>/dev/null
}

############################
## Post-Install functions ##
############################

update_qubesconfig() {
    # Remove old firmware updates link
    if [ -L /lib/firmware/updates ]; then
      rm -f /lib/firmware/updates
    fi

    # convert /usr/local symlink to a mount point
    if [ -L /usr/local ]; then
        rm -f /usr/local
        mkdir /usr/local
        mount /usr/local || :
    fi

    # Fix fstab update to core-agent-linux 4.0.33
    grep -F -q "/rw/usrlocal" /etc/fstab || sed "/\/rw\/home/a\/rw\/usrlocal    \/usr\/local  none    noauto,bind,defaults 0 0" -i /etc/fstab

    #/usr/lib/qubes/update-proxy-configs
    # Archlinux pacman configuration is handled in update_finalize

    if ! [ -r /etc/dconf/profile/user ]; then
        mkdir -p /etc/dconf/profile
        echo "user-db:user" >> /etc/dconf/profile/user
        echo "system-db:local" >> /etc/dconf/profile/user
    fi

    dconf update &> /dev/null || :

    # Location of files which contains list of protected files
    mkdir -p /etc/qubes/protected-files.d
    # shellcheck source=init/functions
    . /usr/lib/qubes/init/functions

    # qubes-core-vm has been broken for some time - it overrides /etc/hosts; restore original content
    if ! is_protected_file /etc/hosts ; then
        if ! grep -q localhost /etc/hosts; then

          cat <<EOF > /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 $(hostname)
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
EOF

        fi
    fi

    # ensure that hostname resolves to 127.0.0.1 resp. ::1 and that /etc/hosts is
    # in the form expected by qubes-sysinit.sh
    if ! is_protected_file /etc/hostname ; then
        for ip in '127\.0\.0\.1' '::1'; do
            if grep -q "^${ip}\(\s\|$\)" /etc/hosts; then
                sed -i "/^${ip}\s/,+0s/\(\s$(hostname)\)\+\(\s\|$\)/\2/g" /etc/hosts
                sed -i "s/^${ip}\(\s\|$\).*$/\0 $(hostname)/" /etc/hosts
            else
                echo "${ip} $(hostname)" >> /etc/hosts
            fi
        done
    fi

}

############################
## Service Management Functions ##
############################
# FIXME: add user units support to is_static()/is_masked()/mask()/unmask() functions
is_static() {
    [ -f "/usr/lib/systemd/system/$1" ] && ! grep -q '^[[].nstall]' "/usr/lib/systemd/system/$1"
}

is_masked() {
    if [ ! -L /etc/systemd/system/"$1" ]
    then
        return 1
    fi
    target=$(readlink /etc/systemd/system/"$1" 2>/dev/null) || :
    if [ "$target" = "/dev/null" ]
    then
        return 0
    fi
    return 1
}

mask() {
    ln -sf /dev/null /etc/systemd/system/"$1"
}

unmask() {
    if ! is_masked "$1"
    then
        return 0
    fi
    rm -f /etc/systemd/system/"$1"
}

preset_units() {
    local represet=
    # shellcheck disable=SC2206
    local extra_opts=( $3 )
    while read -r action unit_name
    do
        if [ "$action" = "#" ] && [ "$unit_name" = "Units below this line will be re-preset on package upgrade" ]
        then
            represet=1
            continue
        fi
        echo "$action $unit_name" | grep -q '^[[:space:]]*[^#;]' || continue
        [[ -n "$action" && -n "$unit_name" ]] || continue
        if [ "$2" = "initial" ] || [ "$represet" = "1" ]
        then
            if [ "$action" = "disable" ] && is_static "$unit_name"
            then
                if ! is_masked "$unit_name"
                then
                    # We must effectively mask these units, even if they are static.
                    mask "$unit_name"
                fi
            elif [ "$action" = "enable" ] && is_static "$unit_name"
            then
                if is_masked "$unit_name"
                then
                    # We masked this static unit before, now we unmask it.
                    unmask "$unit_name"
                fi
                systemctl --no-reload "${extra_opts[@]}" preset "$unit_name" >/dev/null 2>&1 || :
            else
                systemctl --no-reload "${extra_opts[@]}" preset "$unit_name" >/dev/null 2>&1 || :
            fi
        fi
    done < "$1"
}

restore_units() {
    # shellcheck disable=SC2206
    local extra_opts=( $2 )
    grep '^[[:space:]]*[^#;]' "$1" | while read -r action unit_name
    do
        if is_static "$unit_name" && is_masked "$unit_name"
        then
            # If the unit had been masked by us, we must unmask it here.
            # Otherwise systemctl preset will fail badly.
            unmask "$unit_name"
        fi
        systemctl --no-reload "${extra_opts[@]}" preset "$unit_name" >/dev/null 2>&1 || :
    done
}

configure_systemd() {
    if [ "$1" -eq 1 ]
    then
        preset_units /usr/lib/systemd/system-preset/$qubes_preset_file initial
        preset_units /usr/lib/systemd/user-preset/$qubes_preset_file initial --global
        changed=true
    else
        preset_units /usr/lib/systemd/system-preset/$qubes_preset_file upgrade
        preset_units /usr/lib/systemd/user-preset/$qubes_preset_file upgrade --global
        changed=true
        # Upgrade path - now qubes-iptables is used instead
        for svc in iptables ip6tables
        do
            if [ -f "$svc".service ]
            then
                systemctl --no-reload preset "$svc".service
                changed=true
            fi
        done
    fi

    if [ "$1" -eq 1 ]
    then
        # First install.
        # Set default "runlevel".
        # FIXME: this ought to be done via kernel command line.
        # The fewer deviations of the template from the seed
        # image, the better.
        rm -f /etc/systemd/system/default.target
        ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
        changed=true
    fi

    # remove old symlinks
    if [ -L /etc/systemd/system/sysinit.target.wants/qubes-random-seed.service ]
    then
        rm -f /etc/systemd/system/sysinit.target.wants/qubes-random-seed.service
        changed=true
    fi
    if [ -L /etc/systemd/system/multi-user.target.wants/qubes-mount-home.service ]
    then
        rm -f /etc/systemd/system/multi-user.target.wants/qubes-mount-home.service
        changed=true
    fi

    # fix / ro mounted
    ln -sf /usr/lib/systemd/system/systemd-remount-fs.service /etc/systemd/system/sysinit.target.wants/

    if [ "x$changed" != "x" ]
    then
        systemctl daemon-reload
    fi
}

######################
## Archlinux Specific Functions ##
######################
config_prependtomark() {
    FILE=$1
    APPENDBEFORELINE=$2
    APPENDLINE=$3
    grep -F -q "$APPENDLINE" "$FILE" || sed "/$APPENDBEFORELINE/i$APPENDLINE" -i "$FILE"
}

config_appendtomark() {
    FILE=$1
    APPENDAFTERLINE=$2
    APPENDLINE=$3
    grep -F -q "$APPENDLINE" "$FILE" || sed "/$APPENDAFTERLINE/a$APPENDLINE" -i "$FILE"
}

config_cleanupmark() {
    FILE="$1"
    BEGINMARK="$2"
    ENDMARK="$3"
    if grep -F -q "$BEGINMARK" "$FILE"; then
        if grep -F -q "$ENDMARK" "$FILE"; then
            cp "$FILE" "$FILE.qubes-update-orig"
            sed -i -e "/^$BEGINMARK$/,/^$ENDMARK$/{
                /^$ENDMARK$/b
                /^$BEGINMARK$/!d
                }" "$FILE"
            rm -f "$FILE.qubes-update-orig"
        else
            echo "ERROR: found $BEGINMARK marker but not $ENDMARK in $FILE. Please cleanup this file manually."
        fi
    elif grep -F -q "$ENDMARK" "$FILE"; then
        echo "ERROR: found $ENDMARK marker but not $BEGINMARK in $FILE. Please cleanup this file manually."
    fi
}

update_finalize() {
    # Archlinux specific: If marker exists, cleanup text between begin and end marker
    QUBES_MARKER="### QUBES CONFIG MARKER ###"
    if grep -F -q "$QUBES_MARKER" /etc/pacman.conf; then
        config_prependtomark "/etc/pacman.conf" "# REPOSITORIES" "### QUBES CONFIG END MARKER ###"
        config_cleanupmark "/etc/pacman.conf" "$QUBES_MARKER" "### QUBES CONFIG END MARKER ###"
    # Else, add qubes config block marker
    else
        config_prependtomark "/etc/pacman.conf" "# REPOSITORIES" "$QUBES_MARKER"
        config_prependtomark "/etc/pacman.conf" "# REPOSITORIES" "### QUBES CONFIG END MARKER ###"
    fi

    # Include /etc/pacman.d drop-in directory
    config_appendtomark "/etc/pacman.conf" "$QUBES_MARKER" "Include = /etc/pacman.d/*.conf"

    /usr/lib/qubes/update-proxy-configs

    # Archlinux specific: ensure tty1 is enabled
    rm -f /etc/systemd/system/getty.target.wants/getty@tty*.service
    systemctl enable getty\@tty1.service

    systemctl daemon-reload
}

## arg 1:  the new package version
post_install() {
    update_qubesconfig

    # do the rest of %post thing only when updating for the first time...
    if [ -e /etc/init/serial.conf ] && ! [ -f /var/lib/qubes/serial.orig ] ; then
        cp /etc/init/serial.conf /var/lib/qubes/serial.orig
    fi

    chgrp user /var/lib/qubes/dom0-updates

    # Remove most of the udev scripts to speed up the VM boot time
    # Just leave the xen* scripts, that are needed if this VM was
    # ever used as a net backend (e.g. as a VPN domain in the future)
    #echo "--> Removing unnecessary udev scripts..."
    mkdir -p /var/lib/qubes/removed-udev-scripts
    for f in /etc/udev/rules.d/*
    do
        if [ "$(basename "$f")" == "xen-backend.rules" ] ; then
            continue
        fi

        if echo "$f" | grep -q qubes; then
            continue
        fi

        mv "$f" /var/lib/qubes/removed-udev-scripts/
    done

    mkdir -p /rw

    configure_notification-daemon
    configure_selinux

    configure_systemd 0

    update_finalize
}

## arg 1:  the new package version
## arg 2:  the old package version
post_upgrade() {
    update_qubesconfig

    configure_notification-daemon
    configure_selinux

    configure_systemd 1


    update_finalize
}

######################
## Remove functions ##
######################

## arg 1:  the old package version
pre_remove() {
    # no more packages left
    if [ -e /var/lib/qubes/fstab.orig ] ; then
    mv /var/lib/qubes/fstab.orig /etc/fstab
    fi
    mv /var/lib/qubes/removed-udev-scripts/* /etc/udev/rules.d/
    if [ -e /var/lib/qubes/serial.orig ] ; then
    mv /var/lib/qubes/serial.orig /etc/init/serial.conf
    fi

    if [ "$1" -eq 0 ] ; then
        # Run this only during uninstall.
        # Save the preset file to later use it to re-preset services there
        # once the Qubes OS preset file is removed.
        mkdir -p /run/qubes-uninstall
        cp -f /usr/lib/systemd/system-preset/$qubes_preset_file /run/qubes-uninstall/
        cp -f /usr/lib/systemd/user-preset/$qubes_preset_file \
            /run/qubes-uninstall/user-$qubes_preset_file
    fi
}

## arg 1:  the old package version
post_remove() {
    changed=

    if [ -d /run/qubes-uninstall ]
    then
        # We have a saved preset file (or more).
        # Re-preset the units mentioned there.
        restore_units /run/qubes-uninstall/$qubes_preset_file
        restore_units /run/qubes-uninstall/user-$qubes_preset_file --global
        rm -rf /run/qubes-uninstall
        changed=true
    fi

    if [ "x$changed" != "x" ]
    then
        systemctl daemon-reload
    fi


    if [ -L /lib/firmware/updates ] ; then
      rm /lib/firmware/updates
    fi

    rm -rf /var/lib/qubes/xdg

    for srv in qubes-sysinit qubes-misc-post qubes-mount-dirs qubes-qrexec-agent; do
        systemctl disable $srv.service
    done
}