├── .gitignore ├── LICENSE ├── README.md ├── base ├── chrooted │ ├── confs.fish │ ├── main.fish │ ├── users.fish │ └── xbps.fish ├── grub.fish ├── main.fish ├── tabs.fish └── xbps.fish ├── common ├── chroot.fish ├── log.fish └── xbps.fish ├── config.fish ├── disk ├── detect.fish ├── luks.fish ├── main.fish ├── mkdisk.fish └── partition.fish ├── ext ├── chrooted │ ├── cfg.fish │ ├── cron.fish │ ├── dhcp.fish │ ├── firewall.fish │ ├── main.fish │ ├── ntp.fish │ ├── slog.fish │ ├── sys.fish │ └── trim.fish ├── main.fish └── xbps.fish ├── main.fish └── resources ├── COPYING └── genfstab /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 rabbitinspace 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Abyss 2 | 3 | The main purpose of the project is to install a fresh Void Linux system with 4 | Full Disk Encryption. It will not install anything you don't need (see below) 5 | and will leave the system almost like if you would install it by yourself when 6 | following official installation instructions. 7 | 8 | To keep things simple, the following choices were made: 9 | 10 | - Only UEFI systems are supported (yet?). 11 | - Only `glibc` is supported (yet?). 12 | - An entire disk is required for the installation. 13 | - Only Btrfs on LUKS is supported. 14 | - Only GRUB bootloader is supported. 15 | 16 | After installation you'll end up with a system which you can log in into but 17 | there's nothing which can start a graphical session. The only optional package 18 | that will be installed is `fish-shell` which is a runtime dependency and can be 19 | removed right away. 20 | 21 | ## Bugs 22 | 23 | Right now GRUB is always targetings `x86_64-efi` systems which prevents 24 | installation on non x86-64 machines. This is a bug and will be fixed soonj. 25 | 26 | ## Usage 27 | 28 | - Boot from USB drive and install runtime dependencies. 29 | - Clone the repository. 30 | - Alternatively, download latest sources from [here](https://github.com/rabbitinspace/abyss/archive/master.zip). 31 | - Ajust configuration in the [`config.fish`](config.fish). 32 | - Be sure to change `SUPER_STRONG_PASSWORD` to an actual strong LUSK/user password. 33 | - If you don't have SSD, then remove `ssd` from `MOUNT_OPTS` and disable `EXT_TRIM`. 34 | - Run `./main.fish` after `cd`'ing into the project root. 35 | 36 | ### Extended Setup 37 | 38 | You can also choose to do an extended installation which includes few additional 39 | steps: 40 | 41 | - Installs and enables a Cron daemon (`cronie`). 42 | - Installs and enables a NTP daemon (`openntpd`). 43 | - Installs and enables a syslog daemon (`socklog`). 44 | - Enables `iptables` (with shipped rules). 45 | - Enables `dhcpcd`. 46 | - Enables some `sysctl` rules for kernel and networking stack hardening. 47 | - Enables TRIM job for SSD. 48 | 49 | Each of the steps are optional and can be disabled/enabled in [`config.fish`](config.fish). 50 | 51 | ### Runtime Dependencies 52 | 53 | Before installing the system, install these packages: 54 | 55 | - `fish-shell` - shell to run the script. 56 | - `gptfdisk` - GPT-compatible partition utility. 57 | 58 | ## After Installation 59 | 60 | You should be able to boot into the system and log in with the user which you 61 | specified in the configuration file. Now it's time to setup Xorg or Wayland. 62 | 63 | For a quick Xorg installation and configuration you can borrow [bootstrap](https://github.com/rabbitinspace/dotfiles/blob/master/bootstrap) 64 | script from my [dotfiles](https://github.com/rabbitinspace/dotfiles). 65 | 66 | ## Alternatives 67 | 68 | Abyss was inspired by a great [`voidvault`](https://github.com/atweiden/voidvault) 69 | project and provides a subset of it's functionality. Check it out if Abyss 70 | doesn't meet your requirements. 71 | -------------------------------------------------------------------------------- /base/chrooted/confs.fish: -------------------------------------------------------------------------------- 1 | # Sets up permissions for the root filesystem. 2 | function cfg_perm 3 | chown root:root / 4 | chmod 755 / 5 | end 6 | 7 | # Sets hostname. 8 | # Args: 9 | # name - well, it's hostname. 10 | function cfg_hostname -a name 11 | echo $name > /etc/hostname 12 | end 13 | 14 | # Configures system language and enabled locales. 15 | # 16 | # Args: 17 | # $lang - system language to set. 18 | # $locales - comma-separated list of locales to enable. 19 | function cfg_locale -a lang -a locales 20 | # set language 21 | echo "LANG=$lang.UTF-8" > /etc/locale.conf 22 | echo "LC_TIME=$lang.UTF-8" >> /etc/locale.conf 23 | 24 | # enable locales 25 | for locale in (string split ',' $locales) 26 | set -l utf8l "$locale.UTF-8 UTF-8" 27 | set -l path /etc/default/libc-locales 28 | 29 | sed -i "/$utf8l/d" $path 30 | echo $utf8l >> $path 31 | end 32 | end 33 | 34 | # Configures rc.conf. 35 | # 36 | # Args: 37 | # $hwc - hardware clock standard. 38 | # $tz - local timezone. 39 | # $km - keymap to load. 40 | function cfg_rcconf -a hwc -a tz -a km 41 | set -l path /etc/rc.conf 42 | 43 | sed -i "/HARDWARECLOCK/d" $path && echo "HARDWARECLOCK=\"$hwc\"" >> $path 44 | sed -i "/TIMEZONE/d" $path && echo "TIMEZONE=\"$tz\"" >> $path 45 | sed -i "/KEYMAP/d" $path && echo "KEYMAP=\"$km\"" >> $path 46 | 47 | ln -sf "/usr/share/zoneinfo/$tz" /etc/localtime 48 | end 49 | 50 | # Configures dracut. 51 | # 52 | # Args: 53 | # $mods - comma-separated list of modules to load. 54 | function cfg_dracut -a mods 55 | echo 'add_dracutmodules+="crypt btrfs resume"' > /etc/dracut.conf 56 | echo 'tmpdir=/tmp' >> /etc/dracut.conf 57 | 58 | if set -l key (cat /etc/crypttab | grep -Po '/boot/[^\s]+') 59 | mkdir -p /etc/dracut.conf.d/ 60 | echo "install_items+=\"$key /etc/crypttab\"" > /etc/dracut.conf.d/11-crypt.conf 61 | end 62 | 63 | if test -n "$mods" 64 | mkdir -p /etc/dracut.conf.d/ 65 | set -l lmods (echo $mods | string split , | string join " ") 66 | echo "add_dracutmodules+=\"$lmods\"" > /etc/dracut.conf.d/99-addmod.conf 67 | end 68 | end 69 | 70 | # Reconfigures locales, bootloader and initramfs. 71 | function recfg_all 72 | set -l kver (ls /usr/lib/modules | xargs -L 1 basename) || return 1 73 | set -l kmm (echo $kver | string split '.' | head -n 2 | string join '.') 74 | 75 | xbps-reconfigure -f glibc-locales || return 1 76 | dracut --force --kver $kver || return 1 77 | 78 | mkdir -p /boot/grub 79 | grub-mkconfig -o /boot/grub/grub.cfg || return 1 80 | grub-install \ 81 | --target=x86_64-efi \ 82 | --efi-directory=/boot/efi \ 83 | --bootloader-id=void \ 84 | --boot-directory=/boot \ 85 | --recheck || return 1 86 | 87 | xbps-reconfigure -f "linux$kmm" 88 | end 89 | -------------------------------------------------------------------------------- /base/chrooted/main.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | 3 | set DIR (dirname (status --current-filename)) 4 | 5 | source "$DIR/config.fish" 6 | source "$DIR/common/log.fish" 7 | 8 | source "$DIR/confs.fish" 9 | source "$DIR/users.fish" 10 | source "$DIR/xbps.fish" 11 | 12 | function main 13 | __pre_cfg || return 1 14 | __cfg || return 1 15 | __post_cfg || return 1 16 | end 17 | 18 | function __pre_cfg 19 | log_info "Configuring permissions." 20 | if ! cfg_perm 21 | log_err "Failed to configure permissions." 22 | return 1 23 | end 24 | end 25 | 26 | function __cfg 27 | log_info "Configuring hostname." 28 | if ! cfg_hostname $HOSTNAME 29 | log_err "Failed to configure hostname." 30 | return 1 31 | end 32 | 33 | log_info "Configuring locale." 34 | if ! cfg_locale $LANG $LOCALES 35 | log_err "Failed to configure locale." 36 | return 1 37 | end 38 | 39 | log_info "Configuring rc.conf" 40 | if ! cfg_rcconf $HARDWARECLOCK $TIMEZONE $KEYMAP 41 | log_err "Failed to configure rc.conf." 42 | return 1 43 | end 44 | 45 | log_info "Configuring dracut." 46 | if ! cfg_dracut $DRACUT_MODS 47 | log_err "Failed to configure dracut." 48 | return 1 49 | end 50 | 51 | log_info "Reconfiguring system." 52 | if ! recfg_all 53 | log_err "Failed to reconfigure system." 54 | return 1 55 | end 56 | end 57 | 58 | function __post_cfg 59 | log_info "Creating user." 60 | if ! cfg_user $USER_NAME $USER_PASS $USER_GROUPS $USER_SHELL 61 | log_err "Failed to create user." 62 | return 1 63 | end 64 | 65 | log_info "Configuring XBPS repository." 66 | if ! cfg_repo $XBPS_REPO 67 | log_err "Failed to configure XBPS repository." 68 | return 1 69 | end 70 | end 71 | 72 | main $argv 73 | -------------------------------------------------------------------------------- /base/chrooted/users.fish: -------------------------------------------------------------------------------- 1 | # Configures default user. 2 | # 3 | # Args: 4 | # $name - username of the default user. 5 | # $pass - password for the user. 6 | # $groups - groups to add the user to. 7 | # $shell - path to a login shell for the user. 8 | function cfg_user -a name -a pass -a groups -a shell 9 | useradd -m -G $groups -s $shell $name 10 | echo "$name:$pass" | chpasswd -c SHA512 11 | 12 | echo '%wheel ALL=(ALL) ALL' >> /etc/sudoers 13 | passwd -ld root 14 | end 15 | -------------------------------------------------------------------------------- /base/chrooted/xbps.fish: -------------------------------------------------------------------------------- 1 | # Configures default XBPS repository. 2 | # 3 | # Args: 4 | # $url - repository URL to use by default. 5 | function cfg_repo -a url 6 | echo "repository=$url" > /etc/xbps.d/00-repository-main.conf 7 | end 8 | -------------------------------------------------------------------------------- /base/grub.fish: -------------------------------------------------------------------------------- 1 | # Generates and installs a new key to autodecrypt a partition at boot. 2 | # 3 | # This is needed to precent typing decryption password twice on boot. The key 4 | # will be generated using /dev/urandom and stored in /boot directory. 5 | # 6 | # Args: 7 | # $label - label of the LUKS partition. 8 | # $pass - partition decription password. 9 | # $key - name of the key to generate. 10 | # $mnt - mount point where to install key. 11 | function autodecrypt -a label -a pass -a key -a mnt 12 | set -l line (blkid | grep "PARTLABEL=\"$label\"" | grep LUKS) || return 1 13 | set -l part (echo $line | cut -d ':' -f 1) 14 | 15 | dd bs=512 count=4 \ 16 | if=/dev/urandom \ 17 | of="$mnt/boot/$key" \ 18 | status=none || return 1 19 | 20 | echo -n $pass \ 21 | | cryptsetup luksAddKey \ 22 | $part "$mnt/boot/$key" \ 23 | >&2 || return 1 24 | 25 | chmod 000 "$mnt/boot/$key" 26 | chmod -R g-rwx,o-rwx "$mnt/boot" 27 | end 28 | 29 | # Sets default GRUB configuration. 30 | # 31 | # Args: 32 | # $label - label of the root LUKS partition. 33 | # $mnt - mount point of the decrypted LUKS partition. 34 | function set_grub_defaults -a label -a mnt 35 | # get uuid of the LUKS partition 36 | set -l line (blkid | grep "PARTLABEL=\"$label\"" | grep LUKS) || return 1 37 | set -l uuid ( 38 | echo $line \ 39 | | grep -Po '\sUUID=\"[\d\w\-]+\"' \ 40 | | grep -Po '[\d\w\-]+' \ 41 | | tail -n1 42 | ) || return 1 43 | 44 | # grub options we need to be able to boot from encrypted btrfs partition 45 | set -l opts "GRUB_CMDLINE_LINUX=\"rootflags=subvol=@ rd.auto=1 \ 46 | rd.luks.allow-discards cryptdevice=UUID=$uuid:$label\"" 47 | 48 | # backup original config and remove options that we're gonna change 49 | set -l path "$mnt/etc/default/grub" 50 | cp $path "$path.backup" 51 | sed -i "/GRUB_CMDLINE_LINUX/d" $path 52 | sed -i "/GRUB_ENABLE_CRYPTODISK/d" $path 53 | 54 | # write our options 55 | echo "GRUB_ENABLE_CRYPTODISK=y" >> $path 56 | echo $opts >> $path 57 | end 58 | -------------------------------------------------------------------------------- /base/main.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | 3 | set ROOT (type -q git && git rev-parse --show-toplevel 2>/dev/null || pwd) 4 | set DIR (dirname (status --current-filename)) 5 | 6 | source "$ROOT/common/log.fish" 7 | source "$ROOT/common/chroot.fish" 8 | source "$ROOT/common/xbps.fish" 9 | 10 | source "$ROOT/config.fish" 11 | 12 | source "$DIR/xbps.fish" 13 | source "$DIR/tabs.fish" 14 | source "$DIR/grub.fish" 15 | 16 | function main 17 | log_info "Installing base system." 18 | if ! install_base $XBPS_REPO /mnt 19 | log_err "Failed to install base system." 20 | return 1 21 | end 22 | 23 | log_info "Generating fstab." 24 | if ! gen_fstab "$ROOT/resources" /mnt 25 | log_err "Failed to generate fstab." 26 | return 1 27 | end 28 | 29 | log_info "Generating crypttab." 30 | if ! gen_crypttab $LUKS_LABEL $LUKS_KEY /mnt 31 | log_err "Failed to generate crypttab." 32 | return 1 33 | end 34 | 35 | log_info "Enable autodecryption of the root partition." 36 | if ! autodecrypt $LUKS_LABEL $LUKS_PASS $LUKS_KEY /mnt 37 | log_err "Failed to install additional decryption key." 38 | return 1 39 | end 40 | 41 | log_info "Setting GRUB defaults." 42 | if ! set_grub_defaults $LUKS_LABEL /mnt 43 | log_err "Failed to set GRUB defaults." 44 | return 1 45 | end 46 | 47 | log_info "Chrooting for final setup." 48 | if ! run_chrooted /mnt "$DIR/chrooted" $ROOT 49 | log_err "Final setup failed." 50 | return 1 51 | end 52 | end 53 | 54 | main $argv 55 | -------------------------------------------------------------------------------- /base/tabs.fish: -------------------------------------------------------------------------------- 1 | # Generates /etc/fstab. 2 | # 3 | # Fstab will be generated from currently mounted filesystems. 4 | # 5 | # Args: 6 | # $rpath - path to resources directory. 7 | # $mnt - mount point from where to generate fstab. 8 | function gen_fstab -a rpath -a mnt 9 | "$rpath/genfstab" -U $mnt >> "$mnt/etc/fstab" 10 | end 11 | 12 | # Generates /etc/crypttab. 13 | # 14 | # Generates crypttab file to automaticaly decrypt root partition with a keyfile. 15 | # Note, 'discard' mount option will be added added to enable TRIM on SSDs. 16 | # 17 | # Args: 18 | # $label - root partition label. 19 | # $key - path to decryption key. 20 | function gen_crypttab -a label -a key -a mnt 21 | set -l line (blkid | grep "PARTLABEL=\"$label\"" | grep LUKS) || return 1 22 | set -l uuid ( 23 | echo $line \ 24 | | grep -Po '\sUUID=\"[\d\w\-]+\"' \ 25 | | grep -Po '[\d\w\-]+' \ 26 | | tail -n1 27 | ) || return 1 28 | 29 | echo "$label UUID=$uuid /boot/$key luks,discard" >> "$mnt/etc/crypttab" 30 | end 31 | -------------------------------------------------------------------------------- /base/xbps.fish: -------------------------------------------------------------------------------- 1 | # Installs base system packages. 2 | # 3 | # Args: 4 | # $repo - packages repository url. 5 | # $root - installation root directory. 6 | function install_base -a repo -a root 7 | set -l pkgs (__base_packages | string split " ") 8 | set -l mcode (__mcode_pkg) 9 | 10 | xbps_install $repo -r $root $pkgs || return 1 11 | if echo $mcode | string match -qr 'intel' 12 | xbps_install "$repo/nonfree" -r $root $mcode || return 1 13 | else 14 | xbps_install $repo -r $root $mcode || return 1 15 | end 16 | end 17 | 18 | # Prints base system packages to install. 19 | function __base_packages 20 | set -l pkgs \ 21 | base-system \ 22 | cryptsetup \ 23 | btrfs-progs \ 24 | grub-x86_64-efi \ 25 | fish-shell 26 | 27 | echo $pkgs 28 | end 29 | 30 | # Prints microcode package for current cpu. 31 | function __mcode_pkg 32 | set -l vendor (cat /proc/cpuinfo | grep vendor | uniq) 33 | if string match -i '*intel' $vendor >/dev/null 34 | echo intel-ucode 35 | else if string match -i '*amd' $vendor >/dev/null 36 | echo linux-firmware-amd 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /common/chroot.fish: -------------------------------------------------------------------------------- 1 | # Runs a script while being chrooted into another root. 2 | # 3 | # Args: 4 | # $mnt - path to directory to chroot into. 5 | # $path - path to the directory with the 'main.fish' script to run. 6 | # $base - path to the bootscraap directory. 7 | function run_chrooted -a mnt -a path -a base 8 | __bind_sys $mnt || return 1 9 | __copy_path "$mnt/chrooted" $path $base || return 1 10 | 11 | chroot $mnt /bin/fish "/chrooted/main.fish" || return 1 12 | rm -rf "$mnt/chrooted" 13 | __unbind_sys $mnt 14 | end 15 | 16 | # Binds necessary devices and directories into the system. 17 | # 18 | # Args: 19 | # $mnt - mount point of the system. 20 | function __bind_sys -a mnt 21 | for dir in dev proc sys run 22 | mkdir -p "$mnt/$dir" 23 | mount --rbind /$dir "$mnt/$dir" || return 1 24 | mount --make-rslave "$mnt/$dir" || return 1 25 | end 26 | end 27 | 28 | # Unbnids everything that was bound by the __bind_sys function. 29 | # 30 | # Args: 31 | # $mnt - mount point of the system. 32 | function __unbind_sys -a mnt 33 | for dir in dev proc sys run 34 | umount -R "$mnt/$dir" 35 | end 36 | end 37 | 38 | # Copied scripts to run while being chrooted. 39 | # 40 | # Args: 41 | # $mnt - mount point where to copy bootstrap scripts. 42 | # $path - path to directory to copy. 43 | # $base - path to the bootscraap directory. 44 | function __copy_path -a mnt -a path -a base 45 | mkdir -p $mnt 46 | cp -R "$path/." $mnt 47 | cp "$base/config.fish" $mnt 48 | cp -R "$base/common" $mnt 49 | end 50 | -------------------------------------------------------------------------------- /common/log.fish: -------------------------------------------------------------------------------- 1 | # Prints error message. 2 | function log_err -a msg 3 | __log_msg "ERR: $msg" red 4 | end 5 | 6 | # Prints info message. 7 | function log_info -a msg 8 | __log_msg "INF: $msg" normal 9 | end 10 | 11 | # Prints a message to STDERR with a given color. 12 | function __log_msg -a msg -a color 13 | set_color $color 14 | printf "$msg\n" >&2 15 | set_color normal 16 | end 17 | -------------------------------------------------------------------------------- /common/xbps.fish: -------------------------------------------------------------------------------- 1 | # Installs given packages from specified repository. 2 | # 3 | # Args: 4 | # $repo - packages repository url. 5 | # $... - list of packages to install. 6 | function xbps_install -a repo 7 | xbps-install \ 8 | --force \ 9 | --ignore-conf-repos \ 10 | --sync \ 11 | --yes \ 12 | --repository $repo \ 13 | $argv[2..-1] 14 | end 15 | -------------------------------------------------------------------------------- /config.fish: -------------------------------------------------------------------------------- 1 | # 2 | # LUKS 3 | # 4 | 5 | # disk's sector alignment 6 | set LUKS_ALIGN 4096 7 | 8 | # disk encryption password 9 | set LUKS_PASS SUPER_STRONG_PASSWORD 10 | 11 | # name of the key to prevent entering decryption password twice 12 | set LUKS_KEY volume.key 13 | 14 | # label for the mapped root partition 15 | set LUKS_LABEL void 16 | 17 | # 18 | # DRIVES 19 | # 20 | 21 | # mount options for the root partition (remove ssd if not needed) 22 | set MOUNT_OPTS rw,noatime,nodiratime,ssd,compress=zstd,space_cache 23 | 24 | # top-level btrfs subvolumes to create (starts with ',' and no 'boot') 25 | set BTRFS_SUBVOLS ,home,snapshots 26 | 27 | # 28 | # SYSTEM 29 | # 30 | 31 | # machine's hostname 32 | set HOSTNAME void 33 | 34 | # change this if time isn't stored as UTC 35 | set HARDWARECLOCK UTC 36 | 37 | # your timezone 38 | set TIMEZONE Australia/Sydney 39 | 40 | # default keymap to load 41 | set KEYMAP us 42 | 43 | # system language 44 | set LANG en_US 45 | 46 | # comma-separated list of locales 47 | set LOCALES en_US 48 | 49 | # comma-separated list of modules to add to initramfs 50 | set DRACUT_MODS drm 51 | 52 | # 53 | # XBPS 54 | # 55 | 56 | # package manager mirror 57 | set XBPS_REPO https://alpha.de.repo.voidlinux.org/current 58 | 59 | # 60 | # USERS 61 | # 62 | 63 | # name of the default user 64 | set USER_NAME abyss 65 | 66 | # password of the default user 67 | set USER_PASS SUPER_STRONG_PASSWORD 68 | 69 | # comma-separated list of groups to add the user to 70 | set USER_GROUPS wheel,users,audio,video,input,tty,network 71 | 72 | # login shell for the user 73 | set USER_SHELL /bin/bash 74 | 75 | # 76 | # EXTENDED SETUP 77 | # 78 | 79 | # set to no to disable extended configuration 80 | set EXT_SETUP yes 81 | 82 | # install cron daemon (set to no to disable) 83 | set EXT_CRON yes 84 | 85 | # enable dhcp daemon (set to no to disable) 86 | set EXT_DHCP yes 87 | 88 | # install ntp daemon (set to no to disable) 89 | set EXT_NTP yes 90 | 91 | # install syslog daemon (set to no to disable) 92 | set EXT_SLOG yes 93 | 94 | # enable firewall (set to no to disable) 95 | set EXT_FIREWALL yes 96 | 97 | # enable some syscctl rules for kernel hardening (set to no to disable) 98 | set EXT_SYS_RULES yes 99 | 100 | # enable weekly fstrim invocations (set no to disable) 101 | set EXT_TRIM yes 102 | -------------------------------------------------------------------------------- /disk/detect.fish: -------------------------------------------------------------------------------- 1 | # Detects disk to use for installation. 2 | # 3 | # If there's only one disk then it will be used. Otherwise, user will be 4 | # prompted to choose installation disk. 5 | function detect_disk 6 | # read all disks 7 | set -l disks ( 8 | lsblk -o PATH,TYPE \ 9 | | grep disk \ 10 | | cut -d ' ' -f 1 11 | ) 12 | set -l len (count $disks) 13 | 14 | if test $len -eq 0 15 | # return error if no disks 16 | return 1 17 | else if test $len -eq 1 18 | # return the disk if there's no other disks 19 | echo $disks 20 | return 21 | end 22 | 23 | # otherwise ask user to choose 24 | echo "Choose disk to use for installation:" >&2 25 | for i in (seq 1 $len) 26 | echo " $i. $disks[$i]" >&2 27 | end 28 | 29 | set -l choice 0 30 | while ! contains $choice (seq 1 $len) 31 | read choice 32 | end 33 | 34 | # print choosen disk 35 | echo $disks[$choice] 36 | end 37 | -------------------------------------------------------------------------------- /disk/luks.fish: -------------------------------------------------------------------------------- 1 | # Encrypts disk partition. 2 | # 3 | # The partition will be encrypted via dm-crypt using aes-xts-plain64 cipher 4 | # with 512 byets key size (256 for each key part) and sha512 hash. 5 | # The format used is LUKS1. 6 | # 7 | # Args: 8 | # $part - path to the partition to encrypt. 9 | # $pass - password that will be used to decrypt the partition. 10 | # $align - sector alignment. 11 | function encrypt -a part -a pass -a align 12 | echo -n $pass \ 13 | | cryptsetup \ 14 | --type luks1 \ 15 | --cipher aes-xts-plain64 \ 16 | --key-slot 1 \ 17 | --key-size 512 \ 18 | --hash sha512 \ 19 | --align-payload $align \ 20 | luksFormat $part \ 21 | >&2 22 | end 23 | 24 | # Decrypts encrypted partition and prints it's path. 25 | # 26 | # Args: 27 | # $part - path to the encrypted partition. 28 | # $name - name to use for the decrypted partition. 29 | # $pass - decryption password. 30 | function attach -a part -a name -a pass 31 | echo -n $pass \ 32 | | cryptsetup \ 33 | luksOpen $part $name \ 34 | >&2 || return 1 35 | 36 | if test $status -ne 0 37 | return $status 38 | end 39 | 40 | # print name of the mapped disk 41 | echo "/dev/mapper/$name" 42 | end 43 | -------------------------------------------------------------------------------- /disk/main.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | 3 | set ROOT (type -q git && git rev-parse --show-toplevel 2>/dev/null || pwd) 4 | set DIR (dirname (status --current-filename)) 5 | 6 | source "$ROOT/common/log.fish" 7 | source "$ROOT/config.fish" 8 | 9 | source "$DIR/detect.fish" 10 | source "$DIR/luks.fish" 11 | source "$DIR/mkdisk.fish" 12 | source "$DIR/partition.fish" 13 | 14 | # Picks a disk and prepares it for base system installation. 15 | function main 16 | log_info "Detecting disk for installation." 17 | if ! set -l disk (detect_disk) 18 | log_err "Failed to detect disk to use." 19 | return 1 20 | end 21 | 22 | log_info "Partitioning $disk." 23 | if ! partition $disk $LUKS_LABEL $LUKS_ALIGN 24 | log_err "Failed to partition $disk." 25 | return 1 26 | end 27 | 28 | set -l efi (get_partition $disk 1) || return 1 29 | set -l root (get_partition $disk 2) || return 1 30 | 31 | log_info "Encrypting $root." 32 | if ! encrypt $root $LUKS_PASS $LUKS_ALIGN 33 | log_err "Failed to create LUKS partition: $root." 34 | return 1 35 | end 36 | 37 | log_info "Attaching encrypted $root." 38 | if ! set -l mapper (attach $root $LUKS_LABEL $LUKS_PASS) 39 | log_err "Failed to attach LUKS partition: $root." 40 | return 1 41 | end 42 | 43 | log_info "Formatting boot partition: $efi." 44 | if ! mkefi $efi 45 | log_err "Failed to create boot partition: $efi." 46 | return 1 47 | end 48 | 49 | log_info "Formatting root partition: $mapper." 50 | if ! mkbtrfs $mapper $MOUNT_OPTS $BTRFS_SUBVOLS $LUKS_ALIGN /mnt 51 | log_err "Failed to create root partition: $mapper." 52 | return 1 53 | end 54 | 55 | log_info "Mounting all partitions for system installation." 56 | if ! mount_parts $efi $mapper $BTRFS_SUBVOLS $MOUNT_OPTS /mnt 57 | log_err "Failed to mount partition for system installation." 58 | return 1 59 | end 60 | end 61 | 62 | main $argv 63 | -------------------------------------------------------------------------------- /disk/mkdisk.fish: -------------------------------------------------------------------------------- 1 | # Formats given partition to a suitable EFI file system. 2 | # 3 | # Args: 4 | # $part - path to the partition to format. 5 | function mkefi -a part 6 | mkfs.vfat -F32 $part >&2 7 | end 8 | 9 | # Formats given partition to Btrfs and creates nessesary subvolumes. 10 | # 11 | # Args: 12 | # $part - path to the partition to format. 13 | # $opts - mount options to use for subvolume creation. 14 | # $vols - list of subvolumes to create. 15 | # $align - sector alignment. 16 | # $mnt - mount point to use. 17 | function mkbtrfs -a part -a opts -a vols -a align -a mnt 18 | # first, create fs 19 | mkfs.btrfs -s $align $part >&2 || return 1 20 | 21 | # and mount it 22 | mount -o $opts $part $mnt || return 1 23 | 24 | # second, create subvolumes 25 | for vol in (string split ',' $vols) 26 | btrfs subvolume create "$mnt/@$vol" >&2 || return 1 27 | end 28 | 29 | # finally, unmount everything 30 | umount -R $mnt 31 | end 32 | 33 | # Mounts partitions for base system installation. 34 | # 35 | # Args: 36 | # $efi - path to EFI partition. 37 | # $root - path to root Btrfs partition. 38 | # $vols - list of Btrfs subvolumes to mount. 39 | # $opts - mount options for the rool partition. 40 | # $mnt - mount point to use. 41 | function mount_parts -a efi -a root -a vols -a opts -a mnt 42 | # first, mount root partition and it's subvolumes 43 | for vol in (string split ',' $vols) 44 | mkdir -p "$mnt/$vol" 45 | mount -o subvol=@$vol,$opts $root "$mnt/$vol" || return 1 46 | end 47 | 48 | # second, mount boot partition 49 | mkdir -p "$mnt/boot/efi" || return 1 50 | mount $efi "$mnt/boot/efi" || return 1 51 | 52 | # finally, create additional subvolumes 53 | __create_nested_subvols $mnt || return 1 54 | end 55 | 56 | # Creates additional subvolumes for directories where CoW is not needed. 57 | function __create_nested_subvols -a mnt 58 | mkdir -p "$mnt/var/cache" 59 | for vol in var/cache/xbps var/tmp srv 60 | btrfs subvolume create "$mnt/$vol" >&2 || return 1 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /disk/partition.fish: -------------------------------------------------------------------------------- 1 | # Erases and partitions a disk. 2 | # 3 | # The function will erase the disk, convert partition table to GPT 4 | # and create two partitions: EFI system partition and the root partition. 5 | # 6 | # Args: 7 | # $disk - name of the disk to partition. 8 | # $label - GPT label. 9 | # $align - sector alignment. 10 | function partition -a disk -a label -a align 11 | sgdisk --zap-all --clear --mbrtogpt \ 12 | --new 1:0:+550M --typecode 1:EF00 \ 13 | --new 2:0:0 --typecode 2:8300 --set-alignment $align --change-name 2:$label \ 14 | $disk >&2 15 | end 16 | 17 | # Prints name of a disk partition at specific index. 18 | # 19 | # If there's no partition at the provided index, the script will terminate 20 | # the process with code 1. 21 | # 22 | # Args: 23 | # $disk - name of the disk to get partition from. 24 | # $index - index of the partition which name to print. 25 | function get_partition -a disk -a index 26 | set -l partitions ( 27 | lsblk $disk -o PATH,TYPE \ 28 | | grep part \ 29 | | cut -d ' ' -f 1 30 | ) 31 | 32 | if ! contains $index (seq 1 (count $partitions)) 33 | echo "No partition with at index $index" >&2 34 | return 1 35 | end 36 | 37 | echo $partitions[$index] 38 | end 39 | -------------------------------------------------------------------------------- /ext/chrooted/cfg.fish: -------------------------------------------------------------------------------- 1 | # Reconfigures all affected by extended setup packages. 2 | function recfg_all 3 | set -l kver (ls /usr/lib/modules | xargs -L 1 basename) || return 1 4 | set -l kmm (echo $kver | string split '.' | head -n 2 | string join '.') 5 | 6 | dracut --force --kver $kver || return 1 7 | xbps-reconfigure -f "linux$kmm" 8 | end 9 | -------------------------------------------------------------------------------- /ext/chrooted/cron.fish: -------------------------------------------------------------------------------- 1 | function cfg_cron 2 | ln -sf /etc/sv/cronie /var/service/ 3 | end 4 | -------------------------------------------------------------------------------- /ext/chrooted/dhcp.fish: -------------------------------------------------------------------------------- 1 | function cfg_dhcp 2 | ln -sf /etc/sv/dhcpcd /var/service/ 3 | end 4 | -------------------------------------------------------------------------------- /ext/chrooted/firewall.fish: -------------------------------------------------------------------------------- 1 | function cfg_firewall 2 | cp /etc/iptables/simple_firewall.rules /etc/iptables/iptables.rules 3 | __enable_rules 4 | end 5 | 6 | function __enable_rules 7 | set -l run ' 8 | if [ -e /etc/iptables/iptables.rules ]; then 9 | iptables-restore /etc/iptables/iptables.rules 10 | fi 11 | ' 12 | 13 | if ! cat /etc/rc.local | grep iptables-restore >/dev/null 14 | echo $run >> /etc/rc.local 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /ext/chrooted/main.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | 3 | set DIR (dirname (status --current-filename)) 4 | 5 | source "$DIR/config.fish" 6 | source "$DIR/common/log.fish" 7 | source "$DIR/common/xbps.fish" 8 | 9 | source "$DIR/cron.fish" 10 | source "$DIR/dhcp.fish" 11 | source "$DIR/firewall.fish" 12 | source "$DIR/ntp.fish" 13 | source "$DIR/slog.fish" 14 | source "$DIR/sys.fish" 15 | source "$DIR/trim.fish" 16 | source "$DIR/cfg.fish" 17 | 18 | function main 19 | if test $EXT_CRON = yes 20 | log_info "Configuring cron." 21 | if ! cfg_cron 22 | log_err "Failed to configure cron." 23 | end 24 | end 25 | 26 | if test $EXT_DHCP = yes 27 | log_info "Configuring dhcp." 28 | if ! cfg_dhcp 29 | log_err "Failed to configure dhcp." 30 | end 31 | end 32 | 33 | if test $EXT_NTP = yes 34 | log_info "Configuring ntp." 35 | if ! cfg_ntp 36 | log_err "Failed to configure ntp." 37 | end 38 | end 39 | 40 | if test $EXT_SLOG = yes 41 | log_info "Configuring syslog." 42 | if ! cfg_slog 43 | log_err "Failed to configure syslog." 44 | end 45 | end 46 | 47 | if test $EXT_FIREWALL = yes 48 | log_info "Configuring firewall." 49 | if ! cfg_firewall 50 | log_err "Failed to configure firewall." 51 | end 52 | end 53 | 54 | if test $EXT_SYS_RULES = yes 55 | log_info "Configuring sysctl rules." 56 | if ! cfg_sys_rules 57 | log_err "Failed to configure sysctl rues." 58 | end 59 | end 60 | 61 | if test $EXT_TRIM = yes 62 | log_info "Configuring TRIM job." 63 | if ! cfg_trim 64 | log_err "Failed to configure TRIM job." 65 | end 66 | end 67 | 68 | log_info "Re-configuring packages." 69 | if ! recfg_all 70 | log_err "Failed to re-configure packages." 71 | return 1 72 | end 73 | end 74 | 75 | main $argv 76 | -------------------------------------------------------------------------------- /ext/chrooted/ntp.fish: -------------------------------------------------------------------------------- 1 | function cfg_ntp 2 | ln -sf /etc/sv/openntpd /var/service/ 3 | end 4 | -------------------------------------------------------------------------------- /ext/chrooted/slog.fish: -------------------------------------------------------------------------------- 1 | function cfg_slog 2 | ln -sf /etc/sv/socklog-unix /var/service/ 3 | ln -sf /etc/sv/nanoklogd /var/service/ 4 | end 5 | -------------------------------------------------------------------------------- /ext/chrooted/sys.fish: -------------------------------------------------------------------------------- 1 | function cfg_sys_rules 2 | set -l path /etc/sysctl.d/99-sysctl.conf 3 | mkdir -p (dirname $path) 4 | rm -f $path 5 | 6 | __kernel_rules $path 7 | __network_rules $path 8 | end 9 | 10 | function __kernel_rules -a path 11 | # see https://wiki.archlinux.org/index.php/Security#Kernel_hardening 12 | 13 | echo ' 14 | # kernel rules 15 | 16 | kernel.unprivileged_bpf_disabled = 1 17 | net.core.bpf_jit_harden = 2 18 | kernel.randomize_va_space = 2 19 | ' >> $path 20 | end 21 | 22 | function __network_rules -a path 23 | # see https://wiki.archlinux.org/index.php/Sysctl#Networking 24 | 25 | echo ' 26 | # networking rules 27 | 28 | net.core.netdev_max_backlog = 16384 29 | 30 | net.core.somaxconn = 8192 31 | 32 | net.core.rmem_default = 1048576 33 | net.core.rmem_max = 16777216 34 | net.core.wmem_default = 1048576 35 | net.core.wmem_max = 16777216 36 | net.core.optmem_max = 65536 37 | 38 | net.ipv4.tcp_rmem = 4096 1048576 2097152 39 | net.ipv4.tcp_wmem = 4096 65536 16777216 40 | net.ipv4.udp_rmem_min = 8192 41 | net.ipv4.udp_wmem_min = 8192 42 | 43 | net.ipv4.tcp_fastopen = 3 44 | 45 | net.ipv4.tcp_max_syn_backlog = 8192 46 | 47 | net.ipv4.tcp_max_tw_buckets = 2000000 48 | 49 | net.ipv4.tcp_tw_reuse = 1 50 | 51 | net.ipv4.tcp_fin_timeout = 10 52 | 53 | net.ipv4.tcp_slow_start_after_idle = 0 54 | 55 | net.ipv4.tcp_keepalive_time = 60 56 | net.ipv4.tcp_keepalive_intvl = 10 57 | net.ipv4.tcp_keepalive_probes = 6 58 | 59 | net.core.default_qdisc = cake 60 | net.ipv4.tcp_congestion_control = bbr 61 | 62 | net.ipv4.tcp_syncookies = 1 63 | 64 | net.ipv4.tcp_rfc1337 = 1 65 | 66 | net.ipv4.conf.default.rp_filter = 1 67 | net.ipv4.conf.all.rp_filter = 1 68 | 69 | net.ipv4.conf.all.accept_redirects = 0 70 | net.ipv4.conf.default.accept_redirects = 0 71 | net.ipv4.conf.all.secure_redirects = 0 72 | net.ipv4.conf.default.secure_redirects = 0 73 | net.ipv6.conf.all.accept_redirects = 0 74 | net.ipv6.conf.default.accept_redirects = 0 75 | 76 | net.ipv4.icmp_echo_ignore_all = 1 77 | net.ipv6.icmp.echo_ignore_all = 1 78 | ' >> $path 79 | end 80 | -------------------------------------------------------------------------------- /ext/chrooted/trim.fish: -------------------------------------------------------------------------------- 1 | function cfg_trim 2 | set -l path /etc/cron.weekly/fstrim 3 | mkdir -p (dirname $path) 4 | rm -f $path 5 | 6 | __install_script $path || return 1 7 | chmod +x $path 8 | end 9 | 10 | function __install_script -a path 11 | echo " 12 | #!/usr/bin/env sh 13 | fstrim -v -A || true 14 | " > $path 15 | end 16 | -------------------------------------------------------------------------------- /ext/main.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | 3 | set ROOT (type -q git && git rev-parse --show-toplevel 2>/dev/null || pwd) 4 | set DIR (dirname (status --current-filename)) 5 | 6 | source "$ROOT/common/log.fish" 7 | source "$ROOT/common/chroot.fish" 8 | source "$ROOT/common/xbps.fish" 9 | 10 | source "$ROOT/config.fish" 11 | 12 | source "$DIR/xbps.fish" 13 | 14 | function main 15 | if test $EXT_SETUP != yes 16 | log_info "Skipping extended setup." 17 | return 18 | end 19 | 20 | log_info "Installing extended packages." 21 | if ! install_extended $XBPS_REPO /mnt $EXT_CRON $EXT_NTP $EXT_SLOG 22 | log_err "Failed to install extended packages." 23 | return 1 24 | end 25 | 26 | log_info "Chrooting for extended setup." 27 | if ! run_chrooted /mnt "$DIR/chrooted" $ROOT 28 | log_err "Extended setup failed." 29 | return 1 30 | end 31 | end 32 | 33 | main $argv 34 | -------------------------------------------------------------------------------- /ext/xbps.fish: -------------------------------------------------------------------------------- 1 | function install_extended -a repo -a mnt -a cron -a ntp -a slog 2 | if test $cron = yes 3 | xbps_install $repo -r $mnt cronie || return 1 4 | end 5 | 6 | if test $ntp = yes 7 | xbps_install $repo -r $mnt openntpd || return 1 8 | end 9 | 10 | if test $slog = yes 11 | xbps_install $repo -r $mnt socklog-void || return 1 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /main.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | 3 | set DIR (dirname (status --current-filename)) 4 | 5 | function main 6 | "$DIR/disk/main.fish" || return 1 7 | "$DIR/base/main.fish" || return 1 8 | "$DIR/ext/main.fish" || return 1 9 | end 10 | 11 | main $argv 12 | -------------------------------------------------------------------------------- /resources/COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /resources/genfstab: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # source: https://git.archlinux.org/arch-install-scripts.git 3 | # license: GPL2 4 | 5 | shopt -s extglob 6 | 7 | # generated from util-linux source: libmount/src/utils.c 8 | declare -A pseudofs_types=([anon_inodefs]=1 9 | [autofs]=1 10 | [bdev]=1 11 | [bpf]=1 12 | [binfmt_misc]=1 13 | [cgroup]=1 14 | [cgroup2]=1 15 | [configfs]=1 16 | [cpuset]=1 17 | [debugfs]=1 18 | [devfs]=1 19 | [devpts]=1 20 | [devtmpfs]=1 21 | [dlmfs]=1 22 | [efivarfs]=1 23 | [fuse.gvfs-fuse-daemon]=1 24 | [fusectl]=1 25 | [hugetlbfs]=1 26 | [mqueue]=1 27 | [nfsd]=1 28 | [none]=1 29 | [pipefs]=1 30 | [proc]=1 31 | [pstore]=1 32 | [ramfs]=1 33 | [rootfs]=1 34 | [rpc_pipefs]=1 35 | [securityfs]=1 36 | [sockfs]=1 37 | [spufs]=1 38 | [sysfs]=1 39 | [tmpfs]=1) 40 | 41 | # generated from: pkgfile -vbr '/fsck\..+' | awk -F. '{ print $NF }' | sort 42 | declare -A fsck_types=([cramfs]=1 43 | [exfat]=1 44 | [ext2]=1 45 | [ext3]=1 46 | [ext4]=1 47 | [ext4dev]=1 48 | [jfs]=1 49 | [minix]=1 50 | [msdos]=1 51 | [reiserfs]=1 52 | [vfat]=1 53 | [xfs]=1) 54 | 55 | out() { printf "$1 $2\n" "${@:3}"; } 56 | error() { out "==> ERROR:" "$@"; } >&2 57 | warning() { out "==> WARNING:" "$@"; } >&2 58 | msg() { out "==>" "$@"; } 59 | msg2() { out " ->" "$@";} 60 | die() { error "$@"; exit 1; } 61 | 62 | ignore_error() { 63 | "$@" 2>/dev/null 64 | return 0 65 | } 66 | 67 | in_array() { 68 | local i 69 | for i in "${@:2}"; do 70 | [[ $1 = "$i" ]] && return 0 71 | done 72 | return 1 73 | } 74 | 75 | chroot_add_mount() { 76 | mount "$@" && CHROOT_ACTIVE_MOUNTS=("$2" "${CHROOT_ACTIVE_MOUNTS[@]}") 77 | } 78 | 79 | chroot_maybe_add_mount() { 80 | local cond=$1; shift 81 | if eval "$cond"; then 82 | chroot_add_mount "$@" 83 | fi 84 | } 85 | 86 | chroot_setup() { 87 | CHROOT_ACTIVE_MOUNTS=() 88 | [[ $(trap -p EXIT) ]] && die '(BUG): attempting to overwrite existing EXIT trap' 89 | trap 'chroot_teardown' EXIT 90 | 91 | chroot_add_mount proc "$1/proc" -t proc -o nosuid,noexec,nodev && 92 | chroot_add_mount sys "$1/sys" -t sysfs -o nosuid,noexec,nodev,ro && 93 | ignore_error chroot_maybe_add_mount "[[ -d '$1/sys/firmware/efi/efivars' ]]" \ 94 | efivarfs "$1/sys/firmware/efi/efivars" -t efivarfs -o nosuid,noexec,nodev && 95 | chroot_add_mount udev "$1/dev" -t devtmpfs -o mode=0755,nosuid && 96 | chroot_add_mount devpts "$1/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec && 97 | chroot_add_mount shm "$1/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev && 98 | chroot_add_mount /run "$1/run" --bind && 99 | chroot_add_mount tmp "$1/tmp" -t tmpfs -o mode=1777,strictatime,nodev,nosuid 100 | } 101 | 102 | chroot_teardown() { 103 | if (( ${#CHROOT_ACTIVE_MOUNTS[@]} )); then 104 | umount "${CHROOT_ACTIVE_MOUNTS[@]}" 105 | fi 106 | unset CHROOT_ACTIVE_MOUNTS 107 | } 108 | 109 | try_cast() ( 110 | _=$(( $1#$2 )) 111 | ) 2>/dev/null 112 | 113 | valid_number_of_base() { 114 | local base=$1 len=${#2} i= 115 | 116 | for (( i = 0; i < len; i++ )); do 117 | try_cast "$base" "${2:i:1}" || return 1 118 | done 119 | 120 | return 0 121 | } 122 | 123 | mangle() { 124 | local i= chr= out= 125 | local {a..f}= {A..F}= 126 | 127 | for (( i = 0; i < ${#1}; i++ )); do 128 | chr=${1:i:1} 129 | case $chr in 130 | [[:space:]\\]) 131 | printf -v chr '%03o' "'$chr" 132 | out+=\\ 133 | ;; 134 | esac 135 | out+=$chr 136 | done 137 | 138 | printf '%s' "$out" 139 | } 140 | 141 | unmangle() { 142 | local i= chr= out= len=$(( ${#1} - 4 )) 143 | local {a..f}= {A..F}= 144 | 145 | for (( i = 0; i < len; i++ )); do 146 | chr=${1:i:1} 147 | case $chr in 148 | \\) 149 | if valid_number_of_base 8 "${1:i+1:3}" || 150 | valid_number_of_base 16 "${1:i+1:3}"; then 151 | printf -v chr '%b' "${1:i:4}" 152 | (( i += 3 )) 153 | fi 154 | ;; 155 | esac 156 | out+=$chr 157 | done 158 | 159 | printf '%s' "$out${1:i}" 160 | } 161 | 162 | optstring_match_option() { 163 | local candidate pat patterns 164 | 165 | IFS=, read -ra patterns <<<"$1" 166 | for pat in "${patterns[@]}"; do 167 | if [[ $pat = *=* ]]; then 168 | # "key=val" will only ever match "key=val" 169 | candidate=$2 170 | else 171 | # "key" will match "key", but also "key=anyval" 172 | candidate=${2%%=*} 173 | fi 174 | 175 | [[ $pat = "$candidate" ]] && return 0 176 | done 177 | 178 | return 1 179 | } 180 | 181 | optstring_remove_option() { 182 | local o options_ remove=$2 IFS=, 183 | 184 | read -ra options_ <<<"${!1}" 185 | 186 | for o in "${!options_[@]}"; do 187 | optstring_match_option "$remove" "${options_[o]}" && unset 'options_[o]' 188 | done 189 | 190 | declare -g "$1=${options_[*]}" 191 | } 192 | 193 | optstring_normalize() { 194 | local o options_ norm IFS=, 195 | 196 | read -ra options_ <<<"${!1}" 197 | 198 | # remove empty fields 199 | for o in "${options_[@]}"; do 200 | [[ $o ]] && norm+=("$o") 201 | done 202 | 203 | # avoid empty strings, reset to "defaults" 204 | declare -g "$1=${norm[*]:-defaults}" 205 | } 206 | 207 | optstring_append_option() { 208 | if ! optstring_has_option "$1" "$2"; then 209 | declare -g "$1=${!1},$2" 210 | fi 211 | 212 | optstring_normalize "$1" 213 | } 214 | 215 | optstring_prepend_option() { 216 | local options_=$1 217 | 218 | if ! optstring_has_option "$1" "$2"; then 219 | declare -g "$1=$2,${!1}" 220 | fi 221 | 222 | optstring_normalize "$1" 223 | } 224 | 225 | optstring_get_option() { 226 | local opts o 227 | 228 | IFS=, read -ra opts <<<"${!1}" 229 | for o in "${opts[@]}"; do 230 | if optstring_match_option "$2" "$o"; then 231 | declare -g "$o" 232 | return 0 233 | fi 234 | done 235 | 236 | return 1 237 | } 238 | 239 | optstring_has_option() { 240 | local "${2%%=*}" 241 | 242 | optstring_get_option "$1" "$2" 243 | } 244 | 245 | dm_name_for_devnode() { 246 | read dm_name <"/sys/class/block/${1#/dev/}/dm/name" 247 | if [[ $dm_name ]]; then 248 | printf '/dev/mapper/%s' "$dm_name" 249 | else 250 | # don't leave the caller hanging, just print the original name 251 | # along with the failure. 252 | print '%s' "$1" 253 | error 'Failed to resolve device mapper name for: %s' "$1" 254 | fi 255 | } 256 | 257 | fstype_is_pseudofs() { 258 | (( pseudofs_types["$1"] )) 259 | } 260 | 261 | fstype_has_fsck() { 262 | (( fsck_types["$1"] )) 263 | } 264 | 265 | 266 | write_source() { 267 | local src=$1 spec= label= uuid= comment=() 268 | 269 | label=$(lsblk -rno LABEL "$1" 2>/dev/null) 270 | uuid=$(lsblk -rno UUID "$1" 2>/dev/null) 271 | 272 | # bind mounts do not have a UUID! 273 | 274 | case $bytag in 275 | '') 276 | [[ $uuid ]] && comment=("UUID=$uuid") 277 | [[ $label ]] && comment+=("LABEL=$(mangle "$label")") 278 | ;; 279 | LABEL) 280 | spec=$label 281 | [[ $uuid ]] && comment=("$src" "UUID=$uuid") 282 | ;; 283 | UUID) 284 | spec=$uuid 285 | comment=("$src") 286 | [[ $label ]] && comment+=("LABEL=$(mangle "$label")") 287 | ;; 288 | *) 289 | [[ $uuid ]] && comment=("$1" "UUID=$uuid") 290 | [[ $label ]] && comment+=("LABEL=$(mangle "$label")") 291 | [[ $bytag ]] && spec=$(lsblk -rno "$bytag" "$1" 2>/dev/null) 292 | ;; 293 | esac 294 | 295 | [[ $comment ]] && printf '# %s\n' "${comment[*]}" 296 | 297 | if [[ $spec ]]; then 298 | printf '%-20s' "$bytag=$(mangle "$spec")" 299 | else 300 | printf '%-20s' "$(mangle "$src")" 301 | fi 302 | } 303 | 304 | optstring_apply_quirks() { 305 | local varname=$1 fstype=$2 306 | 307 | # SELinux displays a 'seclabel' option in /proc/self/mountinfo. We can't know 308 | # if the system we're generating the fstab for has any support for SELinux (as 309 | # one might install Arch from a Fedora environment), so let's remove it. 310 | optstring_remove_option "$varname" seclabel 311 | 312 | # Prune 'relatime' option for any pseudofs. This seems to be a rampant 313 | # default which the kernel often exports even if the underlying filesystem 314 | # doesn't support it. Example: https://bugs.archlinux.org/task/54554. 315 | if awk -v fstype="$fstype" '$1 == fstype { exit 1 }' /proc/filesystems; then 316 | optstring_remove_option "$varname" relatime 317 | fi 318 | 319 | case $fstype in 320 | f2fs) 321 | # These are Kconfig options for f2fs. Kernels supporting the options will 322 | # only provide the negative versions of these (e.g. noacl), and vice versa 323 | # for kernels without support. 324 | optstring_remove_option "$varname" noacl,acl,nouser_xattr,user_xattr 325 | ;; 326 | vfat) 327 | # Before Linux v3.8, "cp" is prepended to the value of the codepage. 328 | if optstring_get_option "$varname" codepage && [[ $codepage = cp* ]]; then 329 | optstring_remove_option "$varname" codepage 330 | optstring_append_option "$varname" "codepage=${codepage#cp}" 331 | fi 332 | ;; 333 | esac 334 | } 335 | 336 | usage() { 337 | cat </dev/null; then 416 | # this is root. we can't possibly have more than one... 417 | pass=1 foundroot=1 418 | fi 419 | 420 | # if there's no fsck tool available, then only pass=0 makes sense. 421 | if ! fstype_has_fsck "$fstype"; then 422 | pass=0 423 | fi 424 | 425 | if [[ $fsroot != / ]]; then 426 | if [[ $fstype = btrfs ]]; then 427 | opts+=,subvol=${fsroot#/} 428 | else 429 | # it's a bind mount 430 | src=$(findmnt -funcevo TARGET "$src")$fsroot 431 | if [[ $src -ef $target ]]; then 432 | # hrmm, this is weird. we're probably looking at a file or directory 433 | # that was bound into a chroot from the host machine. Ignore it, 434 | # because this won't actually be a valid mount. Worst case, the user 435 | # just re-adds it. 436 | continue 437 | fi 438 | fstype=none 439 | opts+=,bind 440 | pass=0 441 | fi 442 | fi 443 | 444 | # filesystem quirks 445 | case $fstype in 446 | fuseblk) 447 | # well-behaved FUSE filesystems will report themselves as fuse.$fstype. 448 | # this is probably NTFS-3g, but let's just make sure. 449 | if ! newtype=$(lsblk -no FSTYPE "$src") || [[ -z $newtype ]]; then 450 | # avoid blanking out fstype, leading to an invalid fstab 451 | error 'Failed to derive real filesystem type for FUSE device on %s' "$target" 452 | else 453 | fstype=$newtype 454 | fi 455 | ;; 456 | esac 457 | 458 | optstring_apply_quirks "opts" "$fstype" 459 | 460 | # write one line 461 | write_source "$src" 462 | printf '\t%-10s' "/$(mangle "${target#/}")" "$fstype" "$opts" 463 | printf '\t%s %s' "$dump" "$pass" 464 | printf '\n\n' 465 | done 466 | 467 | # handle swaps devices 468 | { 469 | # ignore header 470 | read 471 | 472 | while read -r device type _ _ prio; do 473 | options=defaults 474 | if (( prio >= 0 )); then 475 | options+=,pri=$prio 476 | fi 477 | 478 | # skip files marked deleted by the kernel 479 | [[ $device = *'\040(deleted)' ]] && continue 480 | 481 | if [[ $type = file ]]; then 482 | printf '%-20s' "$device" 483 | elif [[ $device = /dev/dm-+([0-9]) ]]; then 484 | # device mapper doesn't allow characters we need to worry 485 | # about being mangled, and it does the escaping of dashes 486 | # for us in sysfs. 487 | write_source "$(dm_name_for_devnode "$device")" 488 | else 489 | write_source "$(unmangle "$device")" 490 | fi 491 | 492 | printf '\t%-10s\t%-10s\t%-10s\t0 0\n\n' 'none' 'swap' "$options" 493 | done 494 | }