Skip to content

Commit

Permalink
Remove writable paths
Browse files Browse the repository at this point in the history
Instead we can use /etc/fstab and tmpfiles.d

This requires change in core-initrd to pre-run tmpfiles on
core-writable.conf before switch of root.
  • Loading branch information
valentindavid committed Feb 22, 2022
1 parent e52d749 commit f3a9875
Show file tree
Hide file tree
Showing 13 changed files with 321 additions and 325 deletions.
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,6 @@ test:
if !(cd $(TESTDIR) && $$f); then \
exit 1; \
fi; \
done; \
set -ex; for f in $$(pwd)/tests/test_*.sh; do \
sh -e $$f; \
done

# Display a report of files that are (still) present in /etc
Expand Down
151 changes: 151 additions & 0 deletions hook-tests/993-factory-files.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/bin/bash

# This test verifies that /etc/fstab,
# /usr/lib/tmpfiles.d/core-writable.conf and /usr/share/factory are
# synchronized.
#
# * /writable/* entries should be present in core-writable.conf
# and the other way around.
#
# * /run/mnt/data prefix should be used for entries in /etc only
# instead of /writable
#
# * All and only /etc writable entries should be mounted in initrd.
#
# * C entries core-writable.conf should have a file/directory in
# /usr/share/factory.
#
# * Every path but /home should be writable in
# /writable/system-data/{path}
#
# * /home should be writable in /writable/user-data

set -eu

declare -A known_mounts

sysroot="${PWD}"

# First, we check /etc/fstab
while read line; do
#Skip comments/empty lines
if [ "${line%%#*}" = "" ]; then
continue
fi

set -- ${line}

# Read the options
unset bind
case ",$4," in
*,bind,*)
bind=1
;;
esac

unset initrd
case ",$4," in
*,x-initrd.mount,*)
initrd=1
;;
esac

if [ "${bind:+set}" = set ]; then
case "$1" in
/run/mnt/data/system-data/etc/*)
if [ "${initrd:+set}" != set ]; then
echo "/etc files should be mounted in initrd: $1" 1>&2
false
fi
if [ "${1##/run/mnt/data/system-data}" != "$2" ]; then
echo "Expected path ${2}, but got ${1##/run/mnt/data/system-data}" 1>&2
false
fi
known_mounts["$2"]=1
;;
/run/mnt/data/*)
echo "Files outside /etc can use /writable: $1" 1>&2
false
;;
/writable/system-data/etc/*)
echo "Files in /etc should not use /writable: $1" 1>&2
false
;;
/writable/system-data/*)
if [ "${initrd:+set}" = set ]; then
echo "Files outside /etc should not be mounted in initrd: $1" 1>&2
false
fi
if [ "${1##/writable/system-data}" != "$2" ]; then
echo "Expected path ${2}, but got ${1##/writable/system-data}" 1>&2
false
fi
known_mounts["$2"]=1
;;
/writable/user-data)
if [ "$2" != "/home" ]; then
echo "Expected path /home, but got $2" 1>&2
false
fi
if [ "${initrd:+set}" = set ]; then
echo "Files outside /etc should not be mounted in initrd: $1" 1>&2
false
fi
known_mounts["$2"]=1
;;
esac
fi
done <"${sysroot}/etc/fstab"

# Now we can read core-writable.conf
while read line; do
#Skip comments/empty lines
if [ "${line%%#*}" = "" ]; then
continue
fi

set -- ${line}

case "$2" in
/writable/system-data/*)
path="${2##/writable/system-data}"
;;
/writable/user-data)
path="/home"
;;
*)
echo "Unexpected path ${2}" 1>&2
false
;;
esac

# Verify that it was declared in /etc/fstab
if [ ${known_mounts["${path}"]:+set} = set ]; then
unset known_mounts["${path}"]
else
echo "${path} is not mounted" 1>&2
false
fi

# Verify the factory files/directories are present
case "$1" in
C)
copied="/usr/share/factory${2}"
if ! [ -e "${sysroot}${copied}" ]; then
echo "Missing factory file/directory ${copied}" 1>&2
false
fi
;;
d)
;;
*)
echo "Unknown line ${line}" 2>&1
false
;;
esac
done <"${sysroot}/usr/lib/tmpfiles.d/core-writable.conf"

if [ "${#known_mounts[@]}" != 0 ]; then
echo "Writable mounts that are not prepared: ${!known_mounts[@]}" 1>&2
false
fi
6 changes: 0 additions & 6 deletions hooks/991-no-synced-dirs.chroot

This file was deleted.

56 changes: 56 additions & 0 deletions hooks/993-factory-files.chroot
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/bin/bash
#
# tmpfiles.d(5) will copy files from /usr/share/factory. So
# files/directories that need to be populated in /writable have to be
# copied there.
#
# /usr/lib/tmpfiles.d/core-writable.conf is the configuration file
# that describes the copy of those files/directories.

set -eu

# cp -a requires /proc/self/fd in some cases
mount -t proc proc /proc
trap 'umount /proc' EXIT

mkdir -p /usr/share/factory/writable/user-data
cp -aT /home /usr/share/factory/writable/user-data/home

dirs=(
/root
/etc/cloud
/etc/dbus-1
/etc/default/swapfile
/etc/environment
/etc/hosts
/etc/iproute2
/etc/machine-id
/etc/modprobe.d
/etc/modules-load.d
/etc/netplan
/etc/network/if-up.d
/etc/ssh
/etc/sudoers.d
/etc/sysctl.d
/etc/systemd
/etc/udev/rules.d
/etc/update-motd.d
/etc/writable
/var/cache/apparmor
/var/cache/snapd
/var/lib/console-conf
/var/lib/extrausers
/var/lib/misc
/var/lib/private/systemd
/var/lib/snapd
/var/lib/systemd
/var/log
/var/snap
/var/tmp
)

for dir in "${dirs[@]}"; do
parent="$(dirname "${dir}")"
mkdir -p "/usr/share/factory/writable/system-data/${parent}"
cp -aT "${dir}" "/usr/share/factory/writable/system-data/${dir}"
done
49 changes: 49 additions & 0 deletions static/etc/fstab
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/run/mnt/base / none bind,x-initrd.mount,ro 0 0
/run/mnt/data /writable none bind,x-initrd.mount 0 0
/run/mnt/kernel/firmware /usr/lib/firmware none bind,x-initrd.mount,ro 0 0
/run/mnt/kernel/modules /usr/lib/modules none bind,x-initrd.mount,ro 0 0

/run/mnt/data/system-data/etc/cloud /etc/cloud none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/dbus-1 /etc/dbus-1 none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/default/swapfile /etc/default/swapfile none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/environment /etc/environment none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/hosts /etc/hosts none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/iproute2 /etc/iproute2 none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/machine-id /etc/machine-id none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/modprobe.d /etc/modprobe.d none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/modules-load.d /etc/modules-load.d none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/netplan /etc/netplan none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/network/if-up.d /etc/network/if-up.d none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/ssh /etc/ssh none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/sudoers.d /etc/sudoers.d none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/sysctl.d /etc/sysctl.d none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/systemd /etc/systemd none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/udev/rules.d /etc/udev/rules.d none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/update-motd.d /etc/update-motd.d none bind,x-initrd.mount 0 0
/run/mnt/data/system-data/etc/writable /etc/writable none bind,x-initrd.mount 0 0

/run/mnt/ubuntu-seed /var/lib/snapd/seed none bind,ro 0 0

/writable/user-data /home none bind 0 0
/writable/system-data/root /root none bind 0 0
/writable/system-data/snap /snap none bind 0 0

/writable/system-data/var/cache/apparmor /var/cache/apparmor none bind 0 0
/writable/system-data/var/cache/snapd /var/cache/snapd none bind 0 0
/writable/system-data/var/lib/cloud /var/lib/cloud none bind 0 0
/writable/system-data/var/lib/console-conf /var/lib/console-conf none bind 0 0
/writable/system-data/var/lib/dbus /var/lib/dbus none bind 0 0
/writable/system-data/var/lib/dhcp /var/lib/dhcp none bind 0 0
/writable/system-data/var/lib/extrausers /var/lib/extrausers none bind 0 0
/writable/system-data/var/lib/misc /var/lib/misc none bind 0 0
/writable/system-data/var/lib/private/systemd /var/lib/private/systemd none bind 0 0
/writable/system-data/var/lib/snapd /var/lib/snapd none bind 0 0
/writable/system-data/var/lib/systemd /var/lib/systemd none bind 0 0
/writable/system-data/var/log /var/log none bind 0 0
/writable/system-data/var/snap /var/snap none bind 0 0
/writable/system-data/var/tmp /var/tmp none bind 0 0

tmpfs /media tmpfs defaults,mode=0755 0 0
tmpfs /mnt tmpfs defaults,mode=0755 0 0
tmpfs /tmp tmpfs mode=1777,nodev,nosuid 0 0
tmpfs /var/lib/sudo tmpfs defaults,mode=0700 0 0
67 changes: 0 additions & 67 deletions static/etc/system-image/writable-paths

This file was deleted.

Loading

0 comments on commit f3a9875

Please sign in to comment.