├── .gitignore ├── etc ├── config │ ├── includes.binary │ │ └── .disk │ │ │ ├── base_installable │ │ │ ├── cd_type │ │ │ ├── release_notes_url │ │ │ └── info │ ├── includes.chroot │ │ ├── etc │ │ │ ├── hostname │ │ │ ├── fstab │ │ │ ├── icons │ │ │ │ └── default │ │ │ │ │ └── index.theme │ │ │ ├── apt │ │ │ │ └── apt.conf.d │ │ │ │ │ └── 00trustcdrom │ │ │ ├── netplan │ │ │ │ └── 01-network-manager-all.yml │ │ │ └── hosts │ │ └── usr │ │ │ └── lib │ │ │ ├── NetworkManager │ │ │ └── conf.d │ │ │ │ └── 10-globally-managed-devices.conf │ │ │ └── python3 │ │ │ └── dist-packages │ │ │ └── lsb_release.py │ ├── bootloaders │ │ ├── isolinux │ │ │ ├── hdt.c32 │ │ │ ├── isolinux.bin │ │ │ ├── libgpl.c32 │ │ │ ├── menu.c32 │ │ │ ├── ldlinux.c32 │ │ │ ├── libcom32.c32 │ │ │ ├── libmenu.c32 │ │ │ ├── libutil.c32 │ │ │ ├── vesamenu.c32 │ │ │ ├── isolinux.cfg │ │ │ ├── poweroff.c32 │ │ │ ├── live.cfg.in │ │ │ └── stdmenu.cfg │ │ └── grub-pc │ │ │ ├── font.pf2 │ │ │ └── grub.cfg │ ├── package-lists.calamares │ │ ├── desktop.list.chroot_live │ │ ├── pool.list.binary │ │ └── desktop.list.chroot_install │ └── hooks │ │ └── live │ │ ├── set-disk-info.binary │ │ ├── 999-cleanup-apt-cache.chroot │ │ ├── 100-cleanup-chroot.chroot │ │ ├── setup-casper-folder.binary │ │ ├── 004-set-os-info.chroot │ │ ├── 002-install-pacstall.chroot │ │ ├── 098-ubuntu-image-customization.chroot │ │ ├── 000-remove-blacklisted-packages.chroot │ │ └── 099-install-custom-apps.chroot ├── terraform.conf └── auto │ └── config ├── rebuild-list ├── debs └── live-build_20220505_all.deb ├── .gitmodules ├── 0002-remove-WRONGSUITE-error.patch ├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ ├── pp-publish.yml │ ├── pinephone.yml │ ├── iso.yml │ ├── publish.yml │ ├── pinetab.yml │ ├── raspi.yml │ ├── devel.yml │ └── legacy.yml ├── README.md ├── binary_grub-efi ├── ub2r.sh └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | builds/ 2 | tmp/ 3 | -------------------------------------------------------------------------------- /etc/config/includes.binary/.disk/base_installable: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /etc/config/includes.chroot/etc/hostname: -------------------------------------------------------------------------------- 1 | rhino-live 2 | -------------------------------------------------------------------------------- /etc/config/includes.binary/.disk/cd_type: -------------------------------------------------------------------------------- 1 | full_cd/single 2 | -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/hdt.c32: -------------------------------------------------------------------------------- 1 | /usr/lib/syslinux/modules/bios/hdt.c32 -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/isolinux.bin: -------------------------------------------------------------------------------- 1 | /usr/lib/ISOLINUX/isolinux.bin -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/libgpl.c32: -------------------------------------------------------------------------------- 1 | /usr/lib/syslinux/modules/bios/libgpl.c32 -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/menu.c32: -------------------------------------------------------------------------------- 1 | /usr/lib/syslinux/modules/bios/menu.c32 -------------------------------------------------------------------------------- /etc/config/includes.binary/.disk/release_notes_url: -------------------------------------------------------------------------------- 1 | https://blog.rhinolinux.org 2 | -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/ldlinux.c32: -------------------------------------------------------------------------------- 1 | /usr/lib/syslinux/modules/bios/ldlinux.c32 -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/libcom32.c32: -------------------------------------------------------------------------------- 1 | /usr/lib/syslinux/modules/bios/libcom32.c32 -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/libmenu.c32: -------------------------------------------------------------------------------- 1 | /usr/lib/syslinux/modules/bios/libmenu.c32 -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/libutil.c32: -------------------------------------------------------------------------------- 1 | /usr/lib/syslinux/modules/bios/libutil.c32 -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/vesamenu.c32: -------------------------------------------------------------------------------- 1 | /usr/lib/syslinux/modules/bios/vesamenu.c32 -------------------------------------------------------------------------------- /etc/config/includes.chroot/etc/fstab: -------------------------------------------------------------------------------- 1 | /dev/root / ext2 noatime,errors=remount-ro 0 1 2 | -------------------------------------------------------------------------------- /rebuild-list: -------------------------------------------------------------------------------- 1 | # List of rebuilds in case anything goes wrong or anything happens 2 | 3 | -------------------------------------------------------------------------------- /etc/config/includes.binary/.disk/info: -------------------------------------------------------------------------------- 1 | @DISTRO_NAME @VERSION "@CODENAME" - @CHANNEL @ARCH (@DATE) -------------------------------------------------------------------------------- /etc/config/includes.chroot/etc/icons/default/index.theme: -------------------------------------------------------------------------------- 1 | [Icon Theme] 2 | Inherits=Quintom_Ink 3 | -------------------------------------------------------------------------------- /etc/config/includes.chroot/etc/apt/apt.conf.d/00trustcdrom: -------------------------------------------------------------------------------- 1 | APT::Authentication::TrustCDROM "true"; 2 | -------------------------------------------------------------------------------- /debs/live-build_20220505_all.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhino-linux/os/HEAD/debs/live-build_20220505_all.deb -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/isolinux.cfg: -------------------------------------------------------------------------------- 1 | default vesamenu.c32 2 | include stdmenu.cfg 3 | include live.cfg 4 | -------------------------------------------------------------------------------- /etc/config/bootloaders/grub-pc/font.pf2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhino-linux/os/HEAD/etc/config/bootloaders/grub-pc/font.pf2 -------------------------------------------------------------------------------- /etc/config/includes.chroot/usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf: -------------------------------------------------------------------------------- 1 | [keyfile] 2 | unmanaged-devices=none 3 | -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/poweroff.c32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhino-linux/os/HEAD/etc/config/bootloaders/isolinux/poweroff.c32 -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "etc/config/includes.binary/grub"] 2 | path = etc/config/includes.binary/grub 3 | url = https://github.com/rhino-linux/grub.git 4 | -------------------------------------------------------------------------------- /etc/config/package-lists.calamares/desktop.list.chroot_live: -------------------------------------------------------------------------------- 1 | casper 2 | gparted 3 | calamares 4 | qml6-module-qtquick-window 5 | qml6-module-qtquick 6 | squashfs-tools 7 | -------------------------------------------------------------------------------- /etc/config/hooks/live/set-disk-info.binary: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "P: Begin executing set-disk-info binary hook in ${PWD}" 4 | 5 | cp -rf ../config/includes.binary/.disk . 6 | -------------------------------------------------------------------------------- /etc/config/includes.chroot/etc/netplan/01-network-manager-all.yml: -------------------------------------------------------------------------------- 1 | # Let NetworkManager manage all devices on this system 2 | network: 3 | version: 2 4 | renderer: NetworkManager 5 | -------------------------------------------------------------------------------- /etc/config/hooks/live/999-cleanup-apt-cache.chroot: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Description: Cleanup apt cache files that add ~100MB to the .iso that aren't needed 3 | 4 | apt-get autopurge -yq 5 | apt-get clean -q 6 | 7 | rm -rf /var/cache/apt/* /var/lib/apt/lists/* 8 | -------------------------------------------------------------------------------- /etc/config/includes.chroot/etc/hosts: -------------------------------------------------------------------------------- 1 | 127.0.0.1 localhost 2 | 3 | # The following lines are desirable for IPv6 capable hosts 4 | ::1 ip6-localhost ip6-loopback 5 | fe00::0 ip6-localnet 6 | ff00::0 ip6-mcastprefix 7 | ff02::1 ip6-allnodes 8 | ff02::2 ip6-allrouters 9 | ff02::3 ip6-allhosts 10 | -------------------------------------------------------------------------------- /etc/config/package-lists.calamares/pool.list.binary: -------------------------------------------------------------------------------- 1 | b43-fwcutter 2 | dkms 3 | setserial 4 | user-setup 5 | efibootmgr 6 | secureboot-db 7 | shim 8 | shim-signed 9 | 10 | #if ARCHITECTURES arm64 11 | initramfs-tools 12 | grub-efi-arm64 13 | grub-efi-arm64-bin 14 | grub-efi-arm64-signed 15 | #endif 16 | 17 | #if ARCHITECTURES amd64 18 | grub-pc 19 | broadcom-sta-dkms 20 | microcode-initrd 21 | intel-microcode 22 | iucode-tool 23 | #endif 24 | -------------------------------------------------------------------------------- /etc/config/hooks/live/100-cleanup-chroot.chroot: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Cleanup chroot stuff. From https://git.launchpad.net/livecd-rootfs/tree/live-build/ubuntu-cpc/hooks.d/chroot/099-cleanup.chroot 3 | 4 | rm -rf /var/log/fsck /var/log/journal 5 | rm -rf /var/run/* 6 | rm -f /etc/passwd- 7 | rm -f /etc/shadow- 8 | rm -f /etc/gshadow- 9 | rm -f /etc/group- 10 | rm -f /etc/apt/conf.d/00secure 11 | rm -rf /home/rhino-live/.cache 12 | rm -rf /root/.cache 13 | -------------------------------------------------------------------------------- /0002-remove-WRONGSUITE-error.patch: -------------------------------------------------------------------------------- 1 | diff --git a/functions b/functions 2 | index 0ff5379..dd41db4 100644 3 | --- a/functions 4 | +++ b/functions 5 | @@ -570,11 +570,6 @@ validate_suite () { 6 | return 0 7 | fi 8 | done 9 | - if [ "$EXTRA_SUITES" = "" ]; then 10 | - error 1 WRONGSUITE "Asked to install suite %s, but got %s (codename: %s) from mirror" "$SUITE" "$suite" "$CODENAME" 11 | - else 12 | - error 1 WRONGSUITE "Asked to install suites %s %s, but got %s (codename: %s) from mirror" "$SUITE" "$EXTRA_SUITES" "$suite" "$CODENAME" 13 | - fi 14 | } 15 | 16 | split_inline_sig () { 17 | -------------------------------------------------------------------------------- /etc/config/hooks/live/setup-casper-folder.binary: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | mkdir casper || true 4 | mv live/filesystem.squashfs casper/filesystem.squashfs 5 | mv live/filesystem.size casper/filesystem.size 6 | mv live/initrd.img-* casper/initrd.lz 7 | mv live/vmlinuz-* casper/vmlinuz 8 | mv live/filesystem.packages-remove casper/filesystem.manifest-remove 9 | mv live/filesystem.packages casper/filesystem.manifest 10 | mkdir -p casper/boot/grub/themes 11 | cp -rf ../config/includes.binary/grub casper/boot/grub/themes/rhino 12 | printf "$(sudo du -sx --block-size=1 ./ | cut -f1)" > casper/filesystem.size 13 | -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/live.cfg.in: -------------------------------------------------------------------------------- 1 | prompt 0 2 | 3 | MENU HIDDEN 4 | MENU AUTOBOOT Booting Rhino Linux OS live disk in # seconds 5 | timeout 50 6 | 7 | label live-@FLAVOUR@ 8 | menu label ^Try or install Rhino Linux OS 9 | menu default 10 | linux /casper/vmlinuz 11 | initrd /casper/initrd.lz 12 | append @APPEND_LIVE@ 13 | 14 | label live-failsafe 15 | menu label Start Rhino Linux OS (Safe Graphics) 16 | set gfxpayload=keep 17 | linux /casper/vmlinuz 18 | initrd /casper/initrd.lz 19 | append @APPEND_LIVE@ nomodeset 20 | 21 | label hd 22 | menu label ^Boot from next volume 23 | localboot 0x80 24 | 25 | label power 26 | MENU LABEL ^Power Off 27 | COM32 poweroff.c32 28 | -------------------------------------------------------------------------------- /etc/config/hooks/live/004-set-os-info.chroot: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Description: Set Vanilla OS name and info 3 | 4 | # Prepare 5 | distro_pretty_name="@DISTRO_NAME @VERSION @CHANNEL" 6 | 7 | # Set OS name 8 | echo "$distro_pretty_name /\n /\l" >/etc/issue 9 | 10 | # Set OS info 11 | echo 'PRETTY_NAME="'$distro_pretty_name'" 12 | NAME="@DISTRO_NAME" 13 | VERSION_ID="@VERSION" 14 | VERSION="@VERSION @CHANNEL" 15 | VERSION_CODENAME="@CODENAME" 16 | ID=ubuntu 17 | ID_LIKE=debian 18 | HOME_URL="https://rhinolinux.org/" 19 | SUPPORT_URL="https://github.com/rhino-linux" 20 | BUG_REPORT_URL="https://github.com/rhino-linux/tracker" 21 | PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" 22 | UBUNTU_CODENAME="@CODENAME"' >/etc/os-release 23 | -------------------------------------------------------------------------------- /etc/config/hooks/live/002-install-pacstall.chroot: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Description: Add/install Pacstall 3 | 4 | apt-get update -yq 5 | apt-get install axel nano gnome-disk-utility dbus-x11 -yq 6 | 7 | # Create user 8 | sudo groupadd rhino-live 9 | sudo useradd -rm -d /home/rhino-live -g root -s /bin/bash -u 1001 rhino-live 10 | sudo adduser rhino-live sudo 11 | echo '%sudo ALL=(ALL) NOPASSWD:ALL' >>/etc/sudoers # Pacstall has issues with sudo despite the user not having a password 12 | 13 | # More pacstall specific things 14 | export SUDO_USER=rhino-live 15 | export DEBIAN_FRONTEND=noninteractive 16 | export PACSTALL_DOWNLOADER=curl 17 | export GITHUB_ACTIONS=true 18 | 19 | # Install pacstall 20 | echo N | sudo bash -c "$(curl -fsSL https://git.io/JsADh || wget -q https://git.io/JsADh -O -)" 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: 'BUG: [Title]' 5 | labels: bug 6 | assignees: cat-master21, oklopfer 7 | 8 | --- 9 | 10 | **Rhino Linux Version:** 11 | A numerical version for Rhino Linux. Example: `2023.1`, - Version number can be found by running `neofetch` (preinstalled) or with the "Your System" application. 12 | 13 | **Platform:** 14 | [CPU Architecture / Device] 15 | 16 | **Describe the bug** 17 | A clear and concise description of what the bug is. 18 | 19 | **To Reproduce** 20 | Steps to reproduce the behavior: 21 | 1. Go to '...' 22 | 2. Click on '....' 23 | 3. Scroll down to '....' 24 | 4. See error 25 | 26 | **Expected behavior** 27 | A clear and concise description of what you expected to happen. 28 | 29 | **Screenshots** 30 | If applicable, add screenshots to help explain your problem. 31 | 32 | **Additional context** 33 | Add any other context about the problem here. 34 | -------------------------------------------------------------------------------- /etc/config/hooks/live/098-ubuntu-image-customization.chroot: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | # Specific ubuntu-image chroot configuration goes here. 4 | if [ "$IMAGEFORMAT" == "none" ]; then 5 | if [ "$SUBPROJECT" == "desktop-preinstalled" ]; then 6 | touch /var/log/syslog 7 | chown syslog:adm /var/log/syslog 8 | 9 | # Create the oem user account 10 | /usr/sbin/useradd -d /home/oem -G adm,sudo -m -N -u 29999 oem 11 | 12 | /usr/sbin/oem-config-prepare --quiet 13 | touch "/var/lib/oem-config/run" 14 | 15 | # Make the writable partition grow 16 | echo "LABEL=writable / ext4 defaults,x-systemd.growfs 0 0" >>/etc/fstab 17 | 18 | # Create a 1GB swapfile. Now done by lb 19 | #dd if=/dev/zero of=/swapfile bs=1G count=1 20 | #chmod 0600 /swapfile 21 | #mkswap /swapfile 22 | #echo "/swapfile none swap sw 0 0" >>/etc/fstab 23 | fi 24 | fi 25 | 26 | systemctl enable casper-md5check.service 27 | -------------------------------------------------------------------------------- /etc/config/bootloaders/isolinux/stdmenu.cfg: -------------------------------------------------------------------------------- 1 | menu hshift 13 2 | menu width 49 3 | menu margin 8 4 | 5 | # Override the default radial gradient background with black 6 | menu background #ff000000 7 | 8 | # Title bar 9 | menu color title 0 #ffffffff #00000000 * 10 | 11 | # Border Area 12 | menu color border * #00000000 #00000000 none 13 | 14 | # Unselected menu item 15 | menu color unsel 0 #999999 #00000000 * 16 | 17 | # Unselected hotkey 18 | menu color hotkey 0 #999999 #00000000 none 19 | 20 | # Selection bar 21 | menu color sel 0 #ffffff #00000000 none 22 | 23 | # Selected hotkey 24 | menu color hotsel 0 #ffffffff #00000000 none 25 | 26 | # Press [Tab] message 27 | menu color tabmsg 0 #f6f6f6 #00000000 none 28 | 29 | # Timeout message 30 | menu color timeout_msg 0 #f6f6f6 #00000000 none 31 | 32 | # Timeout counter 33 | menu color timeout * #ffffffff #00000000 none 34 | 35 | # Command line 36 | menu color cmdline 0 #ffffffff #00000000 none 37 | 38 | # Command line marker 39 | menu color cmdmark 0 #00000000 #00000000 none 40 | 41 | # Helptest 42 | menu color help 0 #ffffffff #00000000 none 43 | -------------------------------------------------------------------------------- /etc/config/bootloaders/grub-pc/grub.cfg: -------------------------------------------------------------------------------- 1 | if loadfont /boot/grub/font.pf2 ; then 2 | set gfxmode=auto 3 | insmod efi_gop 4 | insmod efi_uga 5 | insmod gfxterm 6 | terminal_output gfxterm 7 | set menu_color_normal=white/black 8 | set menu_color_highlight=black/light-gray 9 | 10 | insmod all_video 11 | insmod png 12 | set theme=/casper/boot/grub/themes/rhino/theme.txt 13 | export theme 14 | set gfxpayload=keep 15 | fi 16 | 17 | set timeout=5 18 | menuentry "Try or Install Rhino Linux OS" { 19 | set gfxpayload=keep 20 | linux /casper/vmlinuz boot=casper quiet splash --- 21 | initrd /casper/initrd.lz 22 | } 23 | menuentry "Try or Install Rhino Linux OS (Safe Graphics)" { 24 | set gfxpayload=keep 25 | linux /casper/vmlinuz boot=casper nomodeset quiet splash --- 26 | initrd /casper/initrd.lz 27 | } 28 | menuentry "OEM install (for manufacturers)" { 29 | set gfxpayload=keep 30 | linux /casper/vmlinuz boot=casper oem-config/enable=true quiet splash --- 31 | initrd /casper/initrd.lz 32 | } 33 | grub_platform 34 | if [ "$grub_platform" = "efi" ]; then 35 | menuentry 'Boot from next volume' { 36 | exit 37 | } 38 | menuentry 'UEFI Firmware Settings' { 39 | fwsetup 40 | } 41 | fi 42 | -------------------------------------------------------------------------------- /etc/terraform.conf: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # target architecture - i386, arm64 or all 4 | ARCH="$(dpkg --print-architecture)" 5 | 6 | # base codename 7 | BASECODENAME="devel" 8 | 9 | # base version 10 | BASEVERSION="devel" 11 | 12 | # distribution codename 13 | CODENAME="devel" 14 | 15 | # distribution version 16 | RELEASE="4" 17 | SUBVER="" 18 | VERSION="$(date +%Y).$RELEASE" 19 | 20 | # full image name 21 | FNAME="Rhino-Linux-$VERSION$SUBVER-$ARCH" 22 | 23 | # distribution channel 24 | #CHANNEL="unstable" 25 | CHANNEL="all" 26 | 27 | # distribution name 28 | DISTRO_NAME="Rhino Linux" 29 | 30 | # disk hostname 31 | NAME="rhino-live" 32 | 33 | # mirror to fetch packages from 34 | if [ $ARCH = arm64 ]; then 35 | MIRROR_URL="http://ports.ubuntu.com/ubuntu-ports/"; 36 | else MIRROR_URL="http://archive.ubuntu.com/ubuntu/"; 37 | fi 38 | 39 | if [ $ARCH = arm64 ]; then 40 | SECURITY_URL="$MIRROR_URL"; 41 | else SECURITY_URL="http://security.ubuntu.com/ubuntu/"; 42 | fi 43 | 44 | # bootloaders tweak 45 | 46 | if [ $ARCH = arm64 ]; then 47 | BOOTLOADERS="grub-efi"; 48 | else BOOTLOADERS="syslinux grub-efi"; 49 | fi 50 | 51 | # suffix for generated .iso files 52 | OUTPUT_SUFFIX="" 53 | 54 | # folder suffix for the package lists to use 55 | PACKAGE_LISTS_SUFFIX="calamares" 56 | -------------------------------------------------------------------------------- /etc/config/hooks/live/000-remove-blacklisted-packages.chroot: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Remove seed branches and remove blacklisted packages 3 | 4 | echo "Fixing snapd not being able to remove itself" 5 | 6 | sed -i 's/^set -e//g' /var/lib/dpkg/info/snapd.prerm # For minimal as snapd fails at some point 7 | sed -i 's/^set -e//g' /var/lib/dpkg/info/snapd.postrm 8 | echo 'rm -rf /snap' >>/var/lib/dpkg/info/snapd.postrm 9 | echo 'rm -rf ~/snap' >>/var/lib/dpkg/info/snapd.postrm 10 | echo 'rm -rf /root/snap' >>/var/lib/dpkg/info/snapd.postrm 11 | 12 | echo "P: Begin executing remove-blacklisted-packages chroot hook..." 13 | 14 | sudo apt-get install qml-module-qtquick2 qml-module-qtquick-window2 -q -y 15 | sudo dpkg --force-depends --remove snapd-seed-glue 16 | 17 | apt-get autoremove --purge -f -q -y \ 18 | ubuntu-desktop \ 19 | ubuntu-session \ 20 | apport \ 21 | snapd \ 22 | update-manager \ 23 | update-notifier \ 24 | gparted \ 25 | sudo-rs 26 | 27 | apt-get install coreutils-from-gnu coreutils-from-uutils- --allow-remove-essential -q -y 28 | 29 | rm -rf ../ubuntu-seeds ../platform 30 | 31 | # Fake desktop entries to prevent some applications from displaying 32 | mkdir -p "/etc/skel/.local/share/applications" "/root" 33 | touch /etc/skel/.local/share/applications/software-properties-drivers.desktop 34 | touch /etc/skel/.local/share/applications/gnome-session-properties.desktop 35 | touch /etc/skel/.local/share/applications/nm-connection-editor.desktop 36 | touch /etc/skel/.local/share/applications/gnome-language-selector.desktop 37 | touch /etc/skel/.local/share/applications/gnome-printers-panel.desktop 38 | touch /etc/skel/.local/share/applications/calamares.desktop 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Issues Tracker 2 | 3 | To report issues or propose new features for this repository, visit [our tracker](https://github.com/rhino-linux/tracker). 4 | 5 | ## Rhino Linux ISO Builder 6 | 7 | --- 8 | Originally forked from [Vanilla-OS's ISO builder](https://github.com/Vanilla-OS/live-iso), which forked from [Cinnamon's ISO builder](https://github.com/ubuntucinnamon/iso-builder-devel), which forked from [Elementary's ISO builder](https://github.com/elementary/os) :) 9 | 10 | --- 11 | 12 | This is the new Rhino Linux (RL) ISO builder (replaces the formerly known [RRR-builder](https://github.com/rollingrhinoremix/RRR-builder)) which creates images from scratch and gives us (even) more control over the final image. To set up the builder: 13 | 14 | - `sudo apt-get update && sudo apt-get install --reinstall debootstrap -y` 15 | - `sudo mv /usr/share/debootstrap/functions functions` 16 | - `sudo patch -i 0002-remove-WRONGSUITE-error.patch` 17 | - `sudo mv functions /usr/share/debootstrap/functions` 18 | - `sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/lunar` 19 | - `sudo dpkg -i debs/live-build_*_all.deb` 20 | - `sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi` 21 | - `sudo chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/` 22 | 23 | Then, to build: 24 | 25 | `sudo ./build.sh etc/terraform.conf` 26 | 27 | The resulting ISO, if successful, will be located in builds/`$ARCH`. The builder should automatically detect whether to build on ARM64 or AMD64, depending on the machine you run it on. **32-bit images are unsupported.** 28 | 29 | This build system creates the images using `lb`/live-build with debootstrap to create images with configuration in `etc` folder. 30 | -------------------------------------------------------------------------------- /etc/config/package-lists.calamares/desktop.list.chroot_install: -------------------------------------------------------------------------------- 1 | gpg 2 | gnupg2 3 | gvfs-fuse 4 | gvfs-backends 5 | curl 6 | bash-completion 7 | blueman 8 | bluez 9 | policykit-1-gnome 10 | polkitd 11 | pkexec 12 | bluez-tools 13 | mate-polkit 14 | network-manager-gnome 15 | alsa-base 16 | alsa-utils 17 | alsa-ucm-conf 18 | bc 19 | ca-certificates 20 | doc-base 21 | ghostscript-x 22 | gtk2-engines-pixbuf 23 | inputattach 24 | language-selector-common 25 | language-pack-en 26 | language-pack-ko 27 | libasound2-plugins 28 | libsasl2-modules 29 | libadwaita-1-0 30 | libpanel-1-1 31 | libdbus-glib-1-2 32 | lightdm 33 | lightdm-gtk-greeter 34 | rfkill 35 | spice-vdagent 36 | thunar 37 | thunar-volman 38 | ubuntu-drivers-common 39 | unzip 40 | libiw30t64 41 | wpasupplicant 42 | xdg-user-dirs 43 | xdg-user-dirs-gtk 44 | xdg-utils 45 | xfce4-goodies 46 | xfce4-appfinder 47 | xfce4-notifyd 48 | xfce4-panel 49 | xfce4-terminal 50 | xfce4-session 51 | xfce4-settings 52 | xfdesktop4 53 | xfwm4 54 | xkb-data 55 | xorg 56 | x11-common 57 | zip 58 | xubuntu-default-settings 59 | systemd 60 | software-properties-common 61 | mousepad 62 | qt6-style-kvantum 63 | qt6-style-kvantum-themes 64 | mugshot 65 | fonts-firacode 66 | mpv 67 | fonts-noto-core 68 | fonts-noto-extra 69 | fonts-noto-cjk 70 | fonts-noto-cjk-extra 71 | wireplumber 72 | pipewire 73 | pipewire-pulse 74 | firmware-sof-signed 75 | cryptsetup-initramfs 76 | net-tools 77 | ifupdown 78 | bridge-utils 79 | command-not-found 80 | user-setup 81 | secureboot-db 82 | shim 83 | shim-signed 84 | mokutil 85 | fwupdate 86 | expect 87 | cifs-utils 88 | xfsprogs 89 | jfsutils 90 | reiserfsprogs 91 | dosfstools 92 | mtools 93 | ntfs-3g 94 | lvm2 95 | wamerican 96 | dracut-core 97 | zram-config 98 | rsync 99 | libglib2.0-bin 100 | btrfs-progs 101 | openssl 102 | sbsigntool 103 | cryptsetup 104 | rclone-browser 105 | wmctrl 106 | -------------------------------------------------------------------------------- /.github/workflows/pp-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish RL PinePhone Images 2 | on: workflow_dispatch 3 | 4 | jobs: 5 | publish: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Checkout repository 9 | uses: actions/checkout@v4 10 | with: 11 | path: os 12 | 13 | - name: Change APT repository URLs because of the Ubuntu Archive slowdowns 14 | run: sudo sed -i 's/azure\.archive\.ubuntu\.com/mirrors.mit.edu/g' /etc/apt/sources.list 15 | 16 | - name: Update APT cache 17 | run: sudo apt-get update 18 | 19 | - name: Install rclone 20 | run: sudo apt-get install rclone -y 21 | 22 | - name: Set up rclone config 23 | run: | 24 | # Normally we'd be able to run something like 25 | # 'rclone config create ...', but that isn't working for some reason. 26 | # So we'll make the config manually instead. 27 | # 28 | # See https://github.com/rhino-linux/os/actions/runs/5396018584/jobs/9799166656 29 | # as an example. 30 | mkdir ~/.config/rclone 31 | echo " 32 | [wasabi] 33 | type = s3 34 | provider = Wasabi 35 | access_key_id = ${{ secrets.WASABI_ACCESS_KEY_ID }} 36 | secret_access_key = ${{ secrets.WASABI_ACCESS_KEY_SECRET }} 37 | endpoint = s3.wasabisys.com 38 | " > ~/.config/rclone/rclone.conf 39 | - name: Download release assets from latest CI run 40 | run: gh run download -p '*' "$(gh run list -w pinephone.yml --json databaseId -q '.[].databaseId' -L 1)" 41 | env: 42 | GH_TOKEN: "${{ github.token }}" 43 | GH_REPO: "${{ github.repository }}" 44 | 45 | - name: Upload assets to Wasabi 46 | run: | 47 | source os/etc/terraform.conf 48 | mkdir builds/ 49 | for iso in *.img.xz; do 50 | mv "${iso}"/"${iso}" builds/ 51 | sha256sum "builds/${iso}" >> "builds/${iso}".sha256 52 | rclone copyto --progress --s3-no-check-bucket "builds/${iso}.sha256" "wasabi:dl.rhinolinux.org/releases/${VERSION}${SUBVER}/${iso}.sha256" 53 | rclone copyto --progress --s3-no-check-bucket "builds/${iso}" "wasabi:dl.rhinolinux.org/releases/${VERSION}${SUBVER}/${iso}"; 54 | done 55 | -------------------------------------------------------------------------------- /.github/workflows/pinephone.yml: -------------------------------------------------------------------------------- 1 | name: RL PinePhone Image Generation 2 | 3 | on: 4 | workflow_dispatch 5 | 6 | jobs: 7 | build_pine_tarball: 8 | runs-on: ubuntu-24.04-arm 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | ref: 'pinephone' 13 | 14 | - name: Install needed packages 15 | run: | 16 | sudo rm -rf /etc/apt/sources.list.d/microsoft-prod.list 17 | sudo rm -rf /var/lib/apt/lists/* 18 | sudo apt-get update && sudo apt-get install debootstrap mtools dosfstools qemu-user-static binfmt-support -y 19 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/lunar 20 | sudo dpkg -i debs/live-build_*_all.deb 21 | sudo mv /usr/share/debootstrap/functions functions 22 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 23 | sudo mv functions /usr/share/debootstrap/functions 24 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 25 | sudo cp binary_rootfs /usr/lib/live/build/binary_rootfs 26 | 27 | - name: Make scripts executable 28 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 29 | 30 | - name: Build tarball 31 | run: sudo ./build.sh etc/terraform.conf 32 | 33 | - uses: actions/cache@v4 34 | with: 35 | path: binary/ 36 | key: tar-pine-${{ github.run_id }} 37 | 38 | deploy_pine: 39 | needs: build_pine_tarball 40 | runs-on: ubuntu-latest 41 | steps: 42 | - uses: actions/checkout@v4 43 | with: 44 | ref: 'pinephone' 45 | 46 | - uses: actions/cache@v4 47 | with: 48 | path: binary/ 49 | key: tar-pine-${{ github.run_id }} 50 | 51 | - name: Deploy to partition 52 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-pinephone-unified.img" -m 10G pinephone-unified.yaml 53 | 54 | - name: Place output folder 55 | run: sudo mkdir -p builds/pine 56 | 57 | - name: Move to output folder and compress 58 | run: | 59 | sudo mv Rhino*unified.img builds/pine/ 60 | sudo xz -v builds/pine/Rhino*unified.img 61 | echo "IMGPP=$(cd builds/pine; ls *.img.xz)" >> $GITHUB_ENV 62 | 63 | - uses: actions/upload-artifact@v4.3.3 64 | with: 65 | name: ${{ env.IMGPP }} 66 | path: builds/pine/${{ env.IMGPP }} 67 | -------------------------------------------------------------------------------- /.github/workflows/iso.yml: -------------------------------------------------------------------------------- 1 | name: Rhino Linux ISO Generation 2 | 3 | on: 4 | workflow_dispatch 5 | 6 | jobs: 7 | build_amd64: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | submodules: recursive 13 | 14 | - name: Install needed packages 15 | run: | 16 | sudo rm -rf /var/lib/apt/lists/* 17 | sudo apt-get update && sudo apt-get install --reinstall debootstrap mtools dosfstools qemu-user-static binfmt-support dpkg-dev -y 18 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/noble 19 | sudo dpkg -i debs/live-build_*_all.deb 20 | sudo mv /usr/share/debootstrap/functions functions 21 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 22 | sudo mv functions /usr/share/debootstrap/functions 23 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 24 | 25 | - name: Make scripts executable 26 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 27 | 28 | - name: Build ISO 29 | run: | 30 | sudo ./build.sh etc/terraform.conf 31 | echo "ISOX64=$(cd builds/amd64; ls *.iso)" >> $GITHUB_ENV 32 | 33 | - uses: actions/upload-artifact@v4.3.3 34 | with: 35 | name: ${{ env.ISOX64 }} 36 | path: builds/amd64/${{ env.ISOX64 }} 37 | 38 | build_arm64: 39 | runs-on: ubuntu-24.04-arm 40 | steps: 41 | - uses: actions/checkout@v4 42 | with: 43 | submodules: recursive 44 | 45 | - name: Install needed packages 46 | run: | 47 | sudo rm -rf /var/lib/apt/lists/* 48 | sudo apt-get update && sudo apt-get install --reinstall debootstrap mtools dosfstools qemu-user-static binfmt-support dpkg-dev -y 49 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/noble 50 | sudo dpkg -i debs/live-build_*_all.deb 51 | sudo mv /usr/share/debootstrap/functions functions 52 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 53 | sudo mv functions /usr/share/debootstrap/functions 54 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 55 | 56 | - name: Make scripts executable 57 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 58 | 59 | - name: Build ISO 60 | run: | 61 | sudo ./build.sh etc/terraform.conf 62 | echo "ISOA64=$(cd builds/arm64; ls *.iso)" >> $GITHUB_ENV 63 | 64 | - uses: actions/upload-artifact@v4.3.3 65 | with: 66 | name: ${{ env.ISOA64 }} 67 | path: builds/arm64/${{ env.ISOA64 }} 68 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish Rhino Linux Images 2 | on: workflow_dispatch 3 | 4 | jobs: 5 | publish: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Checkout repository 9 | uses: actions/checkout@v4 10 | with: 11 | path: os 12 | 13 | - name: Change APT repository URLs because of the Ubuntu Archive slowdowns 14 | run: | 15 | sudo sed -i 's/azure\.archive\.ubuntu\.com/mirrors.mit.edu/g' /etc/apt/sources.list 16 | 17 | - name: Update APT cache 18 | run: sudo apt-get update 19 | 20 | - name: Install rclone 21 | run: sudo apt-get install rclone -y 22 | 23 | - name: Set up rclone config 24 | run: | 25 | mkdir -p /home/runner/.config/rclone 26 | rclone config create sourceforge sftp host frs.sourceforge.net user ${{ secrets.SOURCEFORGE_USER }} shell_type unix use_insecure_cipher true pass ${{ secrets.SOURCEFORGE_PASS }} --obscure 27 | 28 | - name: Download release assets from latest CI run 29 | run: gh run download -p '*' "$(gh run list -w legacy.yml --json databaseId -q '.[].databaseId' -L 1)" 30 | env: 31 | GH_TOKEN: "${{ github.token }}" 32 | GH_REPO: "${{ github.repository }}" 33 | 34 | - name: Upload assets to SourceForge 35 | run: | 36 | source os/etc/terraform.conf 37 | HEADVER="${VERSION}${SUBVER}" 38 | PHONE="${HEADVER}-pinephone" 39 | TAB="${HEADVER}-pinetab" 40 | RPI="${HEADVER}-rpi" 41 | HERE="${PWD}" 42 | for image in *.iso *.img.xz; do 43 | case "${image}" in 44 | *iso) 45 | TRUEVER="$HEADVER" 46 | ;; 47 | *phone*) 48 | TRUEVER="$PHONE" 49 | ;; 50 | *tab*) 51 | TRUEVER="$TAB" 52 | ;; 53 | *rpi*) 54 | TRUEVER="$RPI" 55 | ;; 56 | esac 57 | if ! [[ -d "${TRUEVER}/" ]]; then 58 | mkdir "${TRUEVER}/" 59 | fi 60 | mv "${image}"/"${image}" "${TRUEVER}/" 61 | cd "${TRUEVER}" 62 | sha256sum "${image}" >> "${image}.sha256" 63 | cd "${HERE}" 64 | rclone copyto --progress --sftp-ask-password "${TRUEVER}/${image}.sha256" "sourceforge:/home/frs/project/rhino-linux-builder/${TRUEVER}/${image}.sha256" 65 | rclone copyto --progress --sftp-ask-password "${TRUEVER}/${image}" "sourceforge:/home/frs/project/rhino-linux-builder/${TRUEVER}/${image}"; 66 | done 67 | -------------------------------------------------------------------------------- /etc/auto/config: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | . ./terraform.conf 6 | 7 | lb config noauto \ 8 | --architectures "$ARCH" \ 9 | --mode debian \ 10 | --initramfs live-boot \ 11 | --initsystem systemd \ 12 | --distribution "./$BASECODENAME" \ 13 | --parent-distribution "./$BASECODENAME" \ 14 | --archive-areas "main restricted universe multiverse" \ 15 | --parent-archive-areas "main restricted universe multiverse" \ 16 | --linux-packages linux-image \ 17 | --linux-flavours "generic" \ 18 | --bootappend-live "boot=casper quiet splash" \ 19 | --mirror-bootstrap "$MIRROR_URL" \ 20 | --parent-mirror-bootstrap "$MIRROR_URL" \ 21 | --mirror-chroot-security "$SECURITY_URL" \ 22 | --parent-mirror-chroot-security "$SECURITY_URL" \ 23 | --mirror-binary-security "$SECURITY_URL" \ 24 | --parent-mirror-binary-security "$SECURITY_URL" \ 25 | --mirror-binary "$MIRROR_URL" \ 26 | --parent-mirror-binary "$MIRROR_URL" \ 27 | --keyring-packages ubuntu-keyring \ 28 | --apt-options "--option Acquire::Retries=2 --option Acquire::http::Timeout=45 --yes" \ 29 | --apt-recommends false \ 30 | --cache-packages false \ 31 | --cache-stages false \ 32 | --uefi-secure-boot enable \ 33 | --binary-image iso-hybrid \ 34 | --iso-application "$NAME" \ 35 | --iso-volume "$NAME" \ 36 | --firmware-binary false \ 37 | --firmware-chroot false \ 38 | --chroot-squashfs-compression-type "xz -Xdict-size 1M -b 1M" \ 39 | --zsync false \ 40 | --security true \ 41 | --updates true \ 42 | --debootstrap-options "--exclude=pinephone-tweaks,mobile-tweaks-common,librem5-tweaks,pinetab-tweaks" \ 43 | --swap-file-path /swapfile \ 44 | --swap-file-size 256 \ 45 | --interactive false \ 46 | --debconf-frontend noninteractive \ 47 | --compression xz \ 48 | --checksums md5 \ 49 | --bootloaders "$BOOTLOADERS" \ 50 | "${@}" 51 | 52 | 53 | # replace channel and suite 54 | # sed -i "s/@CHANNEL/$CHANNEL/" config/archives/*.list* 55 | # sed -i "s/@BASECODENAME/$BASECODENAME/" config/archives/*.list* 56 | 57 | DATE=$(date +%Y%m%d) 58 | sed -i "s/@CHANNEL/$CHANNEL/" config/includes.binary/.disk/info 59 | sed -i "s/@CODENAME/$CODENAME/" config/includes.binary/.disk/info 60 | sed -i "s/@ARCH/$ARCH/" config/includes.binary/.disk/info 61 | sed -i "s/@DISTRO_NAME/$NAME/" config/includes.binary/.disk/info 62 | sed -i "s/@VERSION/$VERSION/" config/includes.binary/.disk/info 63 | sed -i "s/@DATE/$DATE/" config/includes.binary/.disk/info 64 | 65 | sed -i "s/@DISTRO_NAME/$DISTRO_NAME/" config/hooks/live/004-set-os-info.chroot 66 | sed -i "s/@VERSION/$VERSION/" config/hooks/live/004-set-os-info.chroot 67 | sed -i "s/@CHANNEL/$CHANNEL/" config/hooks/live/004-set-os-info.chroot 68 | sed -i "s/@CODENAME/$CODENAME/" config/hooks/live/004-set-os-info.chroot 69 | sed -i "s/@BASECODENAME/$BASECODENAME/" config/hooks/live/004-set-os-info.chroot 70 | -------------------------------------------------------------------------------- /.github/workflows/pinetab.yml: -------------------------------------------------------------------------------- 1 | name: RL PineTab Generation 2 | 3 | on: 4 | workflow_dispatch 5 | 6 | jobs: 7 | build_tab_tarball: 8 | runs-on: ubuntu-24.04-arm 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | ref: 'pinetab' 13 | 14 | - name: Install needed packages 15 | run: | 16 | sudo rm -rf /etc/apt/sources.list.d/microsoft-prod.list 17 | sudo rm -rf /var/lib/apt/lists/* 18 | sudo apt-get update && sudo apt-get install debootstrap mtools dosfstools qemu-user-static binfmt-support -y 19 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/lunar 20 | sudo dpkg -i debs/live-build_*_all.deb 21 | sudo mv /usr/share/debootstrap/functions functions 22 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 23 | sudo mv functions /usr/share/debootstrap/functions 24 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 25 | sudo cp binary_rootfs /usr/lib/live/build/binary_rootfs 26 | 27 | - name: Make scripts executable 28 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 29 | 30 | - name: Build tarball 31 | run: sudo ./build.sh etc/terraform.conf 32 | 33 | - uses: actions/cache@v4 34 | with: 35 | path: binary/ 36 | key: tar-tab-${{ github.run_id }} 37 | 38 | deploy_tab1: 39 | needs: build_tab_tarball 40 | runs-on: ubuntu-latest 41 | steps: 42 | - uses: actions/checkout@v4 43 | with: 44 | ref: 'pinetab' 45 | 46 | - uses: actions/cache@v4 47 | with: 48 | path: binary/ 49 | key: tar-tab-${{ github.run_id }} 50 | 51 | - name: Deploy to partition 52 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-pinetab.img" -m 10G pinetab.yaml 53 | 54 | - name: Place output folder 55 | run: sudo mkdir -p builds/tab 56 | 57 | - name: Move to output folder and compress 58 | run: | 59 | sudo mv Rhino*tab.img builds/tab/ 60 | sudo xz -v builds/tab/Rhino*tab.img 61 | echo "IMGPTA=$(cd builds/tab; ls *.img.xz)" >> $GITHUB_ENV 62 | 63 | - uses: actions/upload-artifact@v4.3.3 64 | with: 65 | name: ${{ env.IMGPTA }} 66 | path: builds/tab/${{ env.IMGPTA }} 67 | 68 | deploy_tab2: 69 | needs: build_tab_tarball 70 | runs-on: ubuntu-latest 71 | steps: 72 | - uses: actions/checkout@v4 73 | with: 74 | ref: 'pinetab' 75 | 76 | - uses: actions/cache@v4 77 | with: 78 | path: binary/ 79 | key: tar-tab-${{ github.run_id }} 80 | 81 | - name: Deploy to partition 82 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-pinetab2.img" -m 10G pinetab2.yaml 83 | 84 | - name: Place output folder 85 | run: sudo mkdir -p builds/tab2 86 | 87 | - name: Move to output folder and compress 88 | run: | 89 | sudo mv Rhino*tab2.img builds/tab2/ 90 | sudo xz -v builds/tab2/Rhino*tab2.img 91 | echo "IMGPTB=$(cd builds/tab2; ls *.img.xz)" >> $GITHUB_ENV 92 | 93 | - uses: actions/upload-artifact@v4.3.3 94 | with: 95 | name: ${{ env.IMGPTB }} 96 | path: builds/tab2/${{ env.IMGPTB }} 97 | -------------------------------------------------------------------------------- /.github/workflows/raspi.yml: -------------------------------------------------------------------------------- 1 | name: RL RPi Image Generation 2 | 3 | on: 4 | workflow_dispatch 5 | 6 | jobs: 7 | build_rpi_tarball: 8 | runs-on: ubuntu-24.04-arm 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | ref: 'rpi' 13 | 14 | - name: Install needed packages 15 | run: | 16 | sudo rm -rf /etc/apt/sources.list.d/microsoft-prod.list 17 | sudo rm -rf /var/lib/apt/lists/* 18 | sudo apt-get update && sudo apt-get install debootstrap -y 19 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/lunar 20 | sudo dpkg -i debs/live-build_*_all.deb 21 | sudo mv /usr/share/debootstrap/functions functions 22 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 23 | sudo mv functions /usr/share/debootstrap/functions 24 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 25 | 26 | - name: Make scripts executable 27 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 28 | 29 | - name: Build tarball 30 | run: sudo ./build.sh etc/terraform.conf 31 | 32 | - uses: actions/cache@v4 33 | with: 34 | path: binary/ 35 | key: tar-rpi-${{ github.run_id }} 36 | 37 | deploy_rpi_desktop: 38 | needs: build_rpi_tarball 39 | runs-on: ubuntu-latest 40 | steps: 41 | - uses: actions/checkout@v4 42 | with: 43 | ref: 'rpi' 44 | 45 | - uses: actions/cache@v4 46 | with: 47 | path: binary/ 48 | key: tar-rpi-${{ github.run_id }} 49 | 50 | - name: Deploy to partition 51 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-rpi-desktop.img" -m 10G raspberrypi-desktop.yaml 52 | 53 | - name: Place output folder 54 | run: sudo mkdir -p builds/rpi-desktop 55 | 56 | - name: Move to output folder and compress 57 | run: | 58 | sudo mv Rhino*rpi-desktop.img builds/rpi-desktop/ 59 | sudo xz -v builds/rpi-desktop/Rhino*rpi-desktop.img 60 | echo "IMGRPD=$(cd builds/rpi-desktop; ls *.img.xz)" >> $GITHUB_ENV 61 | 62 | - uses: actions/upload-artifact@v4.3.3 63 | with: 64 | name: ${{ env.IMGRPD }} 65 | path: builds/rpi-desktop/${{ env.IMGRPD }} 66 | 67 | deploy_rpi_server: 68 | needs: build_rpi_tarball 69 | runs-on: ubuntu-latest 70 | steps: 71 | - uses: actions/checkout@v4 72 | with: 73 | ref: 'rpi' 74 | 75 | - uses: actions/cache@v4 76 | with: 77 | path: binary/ 78 | key: tar-rpi-${{ github.run_id }} 79 | 80 | - name: Deploy to partition 81 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-rpi-server.img" -m 10G raspberrypi-server.yaml 82 | 83 | - name: Place output folder 84 | run: sudo mkdir -p builds/rpi-server 85 | 86 | - name: Move to output folder and compress 87 | run: | 88 | sudo mv Rhino*rpi-server.img builds/rpi-server/ 89 | sudo xz -v builds/rpi-server/Rhino*rpi-server.img 90 | echo "IMGRPS=$(cd builds/rpi-server; ls *.img.xz)" >> $GITHUB_ENV 91 | 92 | - uses: actions/upload-artifact@v4.3.3 93 | with: 94 | name: ${{ env.IMGRPS }} 95 | path: builds/rpi-server/${{ env.IMGRPS }} 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /.github/workflows/devel.yml: -------------------------------------------------------------------------------- 1 | name: Rhino Linux Image Generation (Meta) 2 | 3 | on: 4 | workflow_dispatch 5 | 6 | jobs: 7 | build: 8 | strategy: 9 | matrix: 10 | include: 11 | - target: amd64 12 | runs-on: ubuntu-latest 13 | type: iso 14 | - target: arm64 15 | runs-on: ubuntu-24.04-arm 16 | type: iso 17 | - target: pine 18 | runs-on: ubuntu-24.04-arm 19 | type: tarball 20 | ref: pinephone 21 | - target: rpi 22 | runs-on: ubuntu-24.04-arm 23 | type: tarball 24 | ref: rpi 25 | - target: tab 26 | runs-on: ubuntu-24.04-arm 27 | type: tarball 28 | ref: pinetab 29 | runs-on: ${{ matrix.runs-on }} 30 | container: 31 | image: "ubuntu:latest" 32 | options: --privileged 33 | steps: 34 | - uses: actions/checkout@v4 35 | with: 36 | ref: ${{ matrix.ref }} 37 | 38 | - name: Install needed packages 39 | run: | 40 | rm -rf /var/lib/apt/lists/* 41 | apt-get update && apt-get install --reinstall sudo debootstrap mtools dosfstools qemu-user-static binfmt-support dpkg-dev -y 42 | ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/noble 43 | dpkg -i debs/live-build_*_all.deb 44 | mv /usr/share/debootstrap/functions functions 45 | patch -i 0002-remove-WRONGSUITE-error.patch 46 | mv functions /usr/share/debootstrap/functions 47 | cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 48 | 49 | - name: set to tarball 50 | if: matrix.type == 'tarball' 51 | run: cp binary_rootfs /usr/lib/live/build/binary_rootfs || echo "no need to change offsets." 52 | 53 | - name: Make scripts executable 54 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 55 | 56 | - name: Build system image 57 | run: ./build.sh etc/terraform.conf 58 | 59 | - name: export iso filename 60 | if: matrix.type == 'iso' 61 | run: echo "OUT_ISO=$(cd builds/${{ matrix.target }}; ls *.iso)" >> $GITHUB_ENV 62 | 63 | - uses: actions/upload-artifact@v4.3.3 64 | if: matrix.type == 'iso' 65 | with: 66 | name: ${{ env.OUT_ISO }} 67 | path: builds/${{ matrix.target }}/${{ env.OUT_ISO }} 68 | 69 | - uses: actions/cache@v4 70 | if: matrix.type == 'tarball' 71 | with: 72 | path: binary/ 73 | key: tar-${{ matrix.target }}-${{ github.run_id }} 74 | 75 | deploy: 76 | needs: build 77 | runs-on: ubuntu-latest 78 | container: 79 | image: "ubuntu:latest" 80 | options: --privileged 81 | strategy: 82 | matrix: 83 | include: 84 | - target: pinephone-unified 85 | parent: pine 86 | ref: pinephone 87 | out: pinephone-unified 88 | - target: raspberrypi-desktop 89 | parent: rpi 90 | ref: rpi 91 | out: rpi-desktop 92 | - target: raspberrypi-server 93 | parent: rpi 94 | ref: rpi 95 | out: rpi-server 96 | - target: pinetab 97 | parent: tab 98 | ref: pinetab 99 | out: pinetab 100 | - target: pinetab2 101 | parent: tab 102 | ref: pinetab 103 | out: pinetab2 104 | steps: 105 | - uses: actions/checkout@v4 106 | with: 107 | ref: ${{ matrix.ref }} 108 | 109 | - uses: actions/cache@v4 110 | with: 111 | path: binary/ 112 | key: tar-${{ matrix.parent }}-${{ github.run_id }} 113 | 114 | - name: Deploy to partition 115 | run: | 116 | source ./etc/terraform.conf 117 | VER="${VERSION}${SUBVER}" 118 | ./debos-docker --privileged -t image:"Rhino-Linux-${VER}-${{ matrix.out }}.img" -m 10G ${{ matrix.target }}.yaml 119 | 120 | - name: Move to output folder and compress 121 | run: | 122 | mkdir -p builds/${{ matrix.type }} 123 | mv Rhino*${{ matrix.out }}.img builds/${{ matrix.out }}/ 124 | xz -v builds/${{ matrix.out }}/Rhino*${{ matrix.out }}.img 125 | echo "OUT_IMAGE=$(cd builds/${{ matrix.out }}; ls *.img.xz)" >> $GITHUB_ENV 126 | 127 | - uses: actions/upload-artifact@v4.3.3 128 | with: 129 | name: ${{ env.OUT_IMAGE }} 130 | path: builds/${{ matrix.out }}/${{ env.OUT_IMAGE }} 131 | -------------------------------------------------------------------------------- /binary_grub-efi: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ## live-build(7) - System Build Scripts 4 | ## Copyright (C) 2016-2020 The Debian Live team 5 | ## Copyright (C) 2016 Adrian Gibanel Lopez 6 | ## 7 | ## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING. 8 | ## This is free software, and you are welcome to redistribute it 9 | ## under certain conditions; see COPYING for details. 10 | 11 | 12 | set -e 13 | 14 | # Including common functions 15 | [ -e "${LIVE_BUILD}/scripts/build.sh" ] && . "${LIVE_BUILD}/scripts/build.sh" || . /usr/lib/live/build.sh 16 | 17 | # Setting static variables 18 | DESCRIPTION="Prepares and installs Grub based EFI support into binary" 19 | USAGE="${PROGRAM} [--force]" 20 | 21 | # Processing arguments and configuration files 22 | Init_config_data "${@}" 23 | 24 | if [ "${LB_BOOTLOADER_EFI}" != "grub-efi" ]; then 25 | exit 0 26 | fi 27 | 28 | if In_list "${LB_IMAGE_TYPE}" hdd netboot; then 29 | exit 0 30 | fi 31 | 32 | Echo_message "Begin preparing Grub based EFI support..." 33 | 34 | # NOTE: We rely on `binary_grub_cfg` to generate grub.cfg and other configuration files! 35 | 36 | # Requiring stage file 37 | Require_stagefiles config bootstrap 38 | 39 | # Checking stage file 40 | Check_stagefile 41 | 42 | # Acquire lock file 43 | Acquire_lockfile 44 | 45 | # Check architecture 46 | Check_architectures amd64 i386 arm64 armhf 47 | Check_crossarchitectures 48 | 49 | # Checking depends 50 | case "${LB_ARCHITECTURE}" in 51 | amd64|i386) 52 | Check_package chroot /usr/lib/grub/x86_64-efi/configfile.mod grub-efi-amd64-bin 53 | Check_package chroot /usr/lib/grub/i386-efi/configfile.mod grub-efi-ia32-bin 54 | ;; 55 | arm64) 56 | Check_package chroot /usr/lib/grub/arm64-efi/configfile.mod grub-efi-arm64-bin 57 | ;; 58 | armhf) 59 | Check_package chroot /usr/lib/grub/arm-efi/configfile.mod grub-efi-arm-bin 60 | ;; 61 | esac 62 | Check_package chroot /usr/bin/grub-mkimage grub-common 63 | Check_package chroot /usr/bin/mcopy mtools 64 | Check_package chroot /sbin/mkfs.msdos dosfstools 65 | 66 | # Check UEFI Secure Boot setting and depends 67 | # By default (auto) do a best-effort build: if the signed binaries are available use 68 | # them, but don't fail if they are not, just print a warning. 69 | case "${LB_ARCHITECTURE}" in 70 | amd64) 71 | _SB_EFI_PLATFORM="x86_64" 72 | _SB_EFI_NAME="x64" 73 | _SB_EFI_DEB="amd64" 74 | ;; 75 | i386) 76 | _SB_EFI_PLATFORM="i386" 77 | _SB_EFI_NAME="ia32" 78 | _SB_EFI_DEB="ia32" 79 | ;; 80 | arm64) 81 | _SB_EFI_PLATFORM="arm64" 82 | _SB_EFI_NAME="aa64" 83 | _SB_EFI_DEB="arm64" 84 | ;; 85 | armhf) 86 | _SB_EFI_PLATFORM="arm" 87 | _SB_EFI_NAME="arm" 88 | _SB_EFI_DEB="arm" 89 | ;; 90 | esac 91 | 92 | _PRE_SB_PACKAGES="${_LB_PACKAGES}" 93 | _LB_PACKAGES="shim-signed grub-efi-${_SB_EFI_DEB}-signed" 94 | case "${LB_UEFI_SECURE_BOOT}" in 95 | auto) 96 | # Use Check_installed, as Check_package will error out immediately 97 | set +e 98 | Install_packages 99 | set -e 100 | Check_installed chroot /usr/lib/grub/${_SB_EFI_PLATFORM}-efi-signed/gcd${_SB_EFI_NAME}.efi.signed \ 101 | grub-efi-${_SB_EFI_DEB}-signed 102 | _GRUB_INSTALL_STATUS="${INSTALL_STATUS}" 103 | Check_installed chroot /usr/lib/shim/shim${_SB_EFI_NAME}.efi.signed \ 104 | shim-signed 105 | 106 | if [ "${INSTALL_STATUS}" -ne 0 -o "${_GRUB_INSTALL_STATUS}" -ne 0 ] 107 | then 108 | Echo_warning "UEFI Secure Boot disabled due to missing signed Grub/Shim." 109 | else 110 | Echo_message "UEFI Secure Boot support enabled." 111 | fi 112 | ;; 113 | enable) 114 | Check_package chroot /usr/lib/grub/${_SB_EFI_PLATFORM}-efi-signed/gcd${_SB_EFI_NAME}.efi.signed \ 115 | grub-efi-${_SB_EFI_DEB}-signed 116 | Check_package chroot /usr/lib/shim/shim${_SB_EFI_NAME}.efi.signed \ 117 | shim-signed 118 | Install_packages 119 | Echo_message "UEFI Secure Boot support enabled." 120 | ;; 121 | disable) 122 | Echo_message "UEFI Secure Boot support disabled." 123 | ;; 124 | esac 125 | _LB_PACKAGES="${_PRE_SB_PACKAGES}" 126 | 127 | # Restoring cache 128 | Restore_package_cache binary 129 | 130 | # Installing depends 131 | Install_packages 132 | 133 | # Cleanup files that we generate 134 | rm -rf binary/boot/efi.img binary/boot/grub/i386-efi/ binary/boot/grub/x86_64-efi binary/boot/grub/arm64-efi binary/boot/grub/arm-efi 135 | 136 | # This is workaround till both efi-image and grub-cpmodules are put into a binary package 137 | case "${LB_BUILD_WITH_CHROOT}" in 138 | true) 139 | if [ ! -e "${LIVE_BUILD}" ] ; then 140 | LIVE_BUILD_PATH="/usr/lib/live/build" 141 | else 142 | LIVE_BUILD_PATH="${LIVE_BUILD}/scripts/build" 143 | fi 144 | mkdir -p chroot/${LIVE_BUILD_PATH} 145 | cp "${LIVE_BUILD_PATH}/efi-image" "chroot/${LIVE_BUILD_PATH}" 146 | cp "${LIVE_BUILD_PATH}/grub-cpmodules" "chroot/${LIVE_BUILD_PATH}" 147 | 148 | _CHROOT_DIR="" 149 | ;; 150 | 151 | false) 152 | _CHROOT_DIR="chroot" 153 | ;; 154 | esac 155 | ##### 156 | cat >binary.sh <.efi that gets loaded first by the firmware 175 | # - drop a grub.cfg (same reason as below) in the cfg directory as configured 176 | # by the signed grub efi binary creation. This is set dynamically when grub2 is 177 | # built with the ouput of dpkg-vendor, and can be overridden by the builder, so 178 | # we do the same here in live-build. 179 | # - the source paths are taken from shim-signed: 180 | # https://packages.debian.org/sid/amd64/shim-signed/filelist 181 | # and grub-efi-amd64-signed, currently in Ubuntu: 182 | # https://packages.ubuntu.com/xenial/amd64/grub-efi-amd64-signed/filelist 183 | # https://packages.ubuntu.com/bionic/arm64/grub-efi-arm64-signed/filelist 184 | # E.g., gcdx64.efi.signed is the boot loader for removable device, like CD or 185 | # USB flash drive, while grubx64.efi.signed is for hard drive. 186 | # Therefore here gcdx64.efi.signed is used for amd64 and gcdaa64.efi.signed is 187 | # for arm64. 188 | if [ -r ${_CHROOT_DIR}/usr/lib/grub/\$platform-signed/gcd\$efi_name.efi.signed -a \ 189 | -r ${_CHROOT_DIR}/usr/lib/shim/shim\$efi_name.efi.signed -a \ 190 | "${LB_UEFI_SECURE_BOOT}" != "disable" ]; then 191 | cp -a ${_CHROOT_DIR}/usr/lib/grub/\$platform-signed/gcd\$efi_name.efi.signed \ 192 | ${_CHROOT_DIR}/grub-efi-temp/EFI/boot/grub\$efi_name.efi 193 | cp -a ${_CHROOT_DIR}/usr/lib/shim/shim\$efi_name.efi.signed \ 194 | ${_CHROOT_DIR}/grub-efi-temp/EFI/boot/boot\$efi_name.efi 195 | fi 196 | } 197 | 198 | PRE_EFI_IMAGE_PATH="${PATH}" 199 | if [ ! -e "${LIVE_BUILD}" ] ; then 200 | LIVE_BUILD_PATH="/usr/lib/live/build" 201 | else 202 | LIVE_BUILD_PATH="${LIVE_BUILD}/scripts/build" 203 | fi 204 | 205 | PATH="${PATH}:\${LIVE_BUILD_PATH}" # Make sure grub-cpmodules is used as if it was installed in the system 206 | 207 | case "${LB_ARCHITECTURE}" in 208 | amd64|i386) 209 | gen_efi_boot_img "x86_64-efi" "x64" "debian-live/amd64" 210 | gen_efi_boot_img "i386-efi" "ia32" "debian-live/i386" 211 | PATH="\${PRE_EFI_IMAGE_PATH}" 212 | ;; 213 | arm64) 214 | gen_efi_boot_img "arm64-efi" "aa64" "debian-live/arm64" 215 | PATH="\${PRE_EFI_IMAGE_PATH}" 216 | ;; 217 | armhf) 218 | gen_efi_boot_img "arm-efi" "arm" "debian-live/arm" 219 | PATH="\${PRE_EFI_IMAGE_PATH}" 220 | ;; 221 | esac 222 | 223 | 224 | # On some platforms the EFI grub image will be loaded, so grub's root 225 | # variable will be set to the EFI partition. This means that grub will 226 | # look in that partition for a grub.cfg file, and even if it finds it 227 | # it will not be able to find the vmlinuz and initrd. 228 | # Drop a minimal grub.cfg in the EFI partition that sets the root and prefix 229 | # to whatever partition holds the /.disk/info file, and load the grub 230 | # config from that same partition. 231 | mkdir -p ${_CHROOT_DIR}/grub-efi-temp-cfg 232 | cat >${_CHROOT_DIR}/grub-efi-temp-cfg/grub.cfg </dev/null 264 | # the above does not work, for some reason it create a too small img, the below force a more reasonable size 265 | mkfs.msdos -C "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" 8192 -i $(printf "%08x" $((${SOURCE_DATE_EPOCH}%4294967296))) >/dev/null 266 | echo "Size of efi.img (1):"; du -h ${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img 267 | mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::EFI 268 | mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::EFI/boot 269 | mcopy -m -o -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ${_CHROOT_DIR}/grub-efi-temp/EFI/boot/*.efi \ 270 | "::EFI/boot" 271 | 272 | mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::boot 273 | mmd -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ::boot/grub 274 | mcopy -m -o -i "${_CHROOT_DIR}/grub-efi-temp/boot/grub/efi.img" ${_CHROOT_DIR}/grub-efi-temp-cfg/grub.cfg \ 275 | "::boot/grub" 276 | END 277 | 278 | case "${LB_BUILD_WITH_CHROOT}" in 279 | true) 280 | mv binary.sh chroot/ 281 | Chroot chroot "sh binary.sh" 282 | rm -f chroot/binary.sh 283 | 284 | # Saving cache 285 | Save_package_cache binary 286 | 287 | # Removing depends. Some bootloader packages are marked as Protected/Important 288 | # in Ubuntu, so temporarily add an apt flag to allow them to be removed 289 | PRE_APT_OPTIONS="${APT_OPTIONS}" 290 | APT_OPTIONS="${APT_OPTIONS} --allow-remove-essential" 291 | Remove_packages 292 | APT_OPTIONS="${PRE_APT_OPTIONS}" 293 | ;; 294 | 295 | false) 296 | sh binary.sh 297 | rm -f binary.sh 298 | ;; 299 | esac 300 | 301 | # Remove unnecessary files 302 | rm -f chroot/grub-efi-temp/bootnetia32.efi 303 | rm -f chroot/grub-efi-temp/bootnetx64.efi 304 | rm -f chroot/grub-efi-temp/bootnetaa64.efi 305 | rm -f chroot/grub-efi-temp/bootnetarm.efi 306 | 307 | mkdir -p binary 308 | cp -a chroot/grub-efi-temp/* binary/ 309 | rm -rf chroot/grub-efi-temp-x86_64-efi 310 | rm -rf chroot/grub-efi-temp-i386-efi 311 | rm -rf chroot/grub-efi-temp-arm64-efi 312 | rm -rf chroot/grub-efi-temp-arm-efi 313 | rm -rf chroot/grub-efi-temp-cfg 314 | rm -rf chroot/grub-efi-temp 315 | 316 | # Creating stage file 317 | Create_stagefile 318 | -------------------------------------------------------------------------------- /etc/config/hooks/live/099-install-custom-apps.chroot: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Description: Install custom Pacstall apps and others 3 | 4 | # More pacstall specific things 5 | export SUDO_USER=rhino-live 6 | export DEBIAN_FRONTEND=noninteractive 7 | export PACSTALL_DOWNLOADER=wget 8 | export GITHUB_ACTIONS=true 9 | 10 | #Pacstall dirs 11 | sudo mkdir -p /var/log/pacstall/metadata /var/log/pacstall/error_log /tmp/pacstall /var/cache/pacstall /usr/src/pacstall 12 | sudo chown "rhino-live" -cR "/var/log/pacstall" 13 | sudo chmod -R 777 "/tmp/pacstall" 14 | sudo chown "rhino-live" -cR "/usr/src/pacstall" 15 | sudo chown "rhino-live" -cR "/tmp/pacstall" 16 | sudo chown "rhino-live" -cR "/usr/share/pacstall" 17 | sudo chown "rhino-live" -cR "/home/rhino-live" 18 | sudo chown "rhino-live" -cR "/var/cache/pacstall" 19 | git config --global --add safe.directory '*' 20 | 21 | sudo mkdir -p /root/.config/gtk-3.0 /home/rhino-live/.config/gtk-3.0 /root/.config/gtk-4.0 /home/rhino-live/.config/gtk-4.0 22 | SUDO_USER=rhino-live pacstall -QPINs nala-deb firefox-bin vscodium-deb linux-kernel-stable rhino-core quintom-cursor-theme-git rhino-grub-theme-git rhino-calamares-settings-git timeshift fake-ubuntu-advantage-tools-deb rhino-setup-bin hello-rhino-bin 23 | 24 | sudo sed -i 's/%sudo ALL=(ALL) NOPASSWD:ALL//' /etc/sudoers 25 | 26 | #Hack: rhino landing 27 | echo 'pref("browser.startup.homepage", "https://rhinolinux.org/landing/", locked);' >>/lib/firefox/defaults/pref/syspref.js 28 | 29 | #Bash colors 30 | sudo cp "/etc/xdg/xdg-unicorn/.bashrc" "/home/rhino-live/.bashrc" 31 | 32 | #Theming 33 | sudo update-alternatives --install /usr/share/icons/default/index.theme x-cursor-theme /usr/share/icons/Quintom_Snow/cursor.theme 55 34 | sudo update-alternatives --install /usr/share/icons/default/index.theme x-cursor-theme /usr/share/icons/Quintom_Ink/cursor.theme 55 35 | sudo update-alternatives --install /usr/share/plymouth/themes/default.plymouth default.plymouth /usr/share/plymouth/themes/rhino-spinner/rhino-spinner.plymouth 100 36 | sudo update-alternatives --set default.plymouth /usr/share/plymouth/themes/rhino-spinner/rhino-spinner.plymouth 37 | sudo update-alternatives --set x-cursor-theme /usr/share/icons/Quintom_Ink/cursor.theme 38 | echo "export QT_STYLE_OVERRIDE=kvantum" | sudo tee -a /etc/environment >/dev/null 39 | mkdir -p /home/rhino-live/.config/Kvantum 40 | mkdir -p /etc/skel/.config/Kvantum 41 | echo "theme=KvRhinoDark" >>/home/rhino-live/.config/Kvantum/kvantum.kvconfig 42 | echo "theme=KvRhinoDark" >>/etc/skel/.config/Kvantum/kvantum.kvconfig 43 | xfconf-query -c xsettings -p /Net/ThemeName --set "Yaru-purple-dark" 44 | HOME=/home/rhino-live runuser -l rhino-live -c 'DISPLAY=:0 XAUTHORITY=/home/rhino-live/.Xauthority DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus gsettings set org.gnome.desktop.interface gtk-theme Yaru-purple' 45 | HOME=/home/rhino-live runuser -l rhino-live -c 'DISPLAY=:0 XAUTHORITY=/home/rhino-live/.Xauthority DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus xfconf-query -c xfwm4 -p /general/theme -s Yaru-dark' 46 | HOME=/home/rhino-live runuser -l rhino-live -c 'DISPLAY=:0 XAUTHORITY=/home/rhino-live/.Xauthority DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus xfconf-query -c xsettings -p /Net/IconThemeName -s Papirus-Dark' 47 | HOME=/home/rhino-live runuser -l rhino-live -c 'DISPLAY=:0 XAUTHORITY=/home/rhino-live/.Xauthority DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus xfconf-query -c xsettings -p /Gtk/CursorThemeName -s Quintom_Ink' 48 | sudo sed -i "s/'Adwaita'/'Yaru-purple-dark'/g" /usr/share/glib-2.0/schemas/org.gnome.desktop.interface.gschema.xml 49 | sudo sed -i "s/'default'/'prefer-dark'/g" /usr/share/glib-2.0/schemas/org.gnome.desktop.interface.gschema.xml 50 | sudo glib-compile-schemas /usr/share/glib-2.0/schemas 51 | 52 | # Grub 53 | echo "GRUB_THEME=/usr/share/grub/themes/rhino/theme.txt" | sudo tee -a /etc/default/grub >/dev/null 54 | sudo update-grub 55 | 56 | mkdir -p /home/rhino-live/Desktop/ 57 | 58 | echo '[Desktop Entry] 59 | Type=Application 60 | Version=1.0 61 | Name=Install Rhino Linux 62 | Name[ca]=Instal·lar Rhino Linux 63 | Name[da]=Installer Rhino Linux 64 | Name[de]=Rhino Linux installieren 65 | Name[es]=Instalar Rhino Linux 66 | Name[fr]=Installer Rhino Linux 67 | Name[it]=Installa Rhino Linux 68 | Name[no]=Installer Rhino Linux 69 | Name[pl]=Zainstaluj Rhino Linux 70 | Name[pt]=Instalar o Rhino Linux 71 | Name[pt_BR]=Instalar Rhino Linux 72 | GenericName=Install Rhino Linux 73 | GenericName[ar]=تنصيب لوبينتو 74 | GenericName[ca]=Instal·lar Rhino Linux 75 | GenericName[da]=Installer Rhino Linux 76 | GenericName[de]=Rhino Linux installieren 77 | GenericName[es]=Instalar Rhino Linux 78 | GenericName[fr]=Installer Rhino Linux 79 | GenericName[it]=Installa Rhino Linux 80 | GenericName[no]=Installer Rhino Linux 81 | GenericName[pl]=Zainstaluj Rhino Linux 82 | GenericName[pt]=Instalar o Rhino Linux 83 | GenericName[pt_BR]=Instalar Rhino Linux 84 | Exec=sudo -E calamares -D6 85 | Comment=Calamares — System Installer 86 | Comment[ar]=الحبار — منصب النظام 87 | Comment[ca]=Calamares — Instal·lador del Sistema 88 | Comment[da]=Calamares - System installation 89 | Comment[de]=Calamares — System Installer 90 | Comment[es]=Calamares — Instalador del Sistema 91 | Comment[fr]=Calamares — Installateur de votre system 92 | Comment[it]=Calamares — Installatore del Sistema 93 | Comment[no]=Calamares — System installerer 94 | Comment[pl]=Calamares — Instalator systemu 95 | Comment[pt]=Calamares — Instalador do Sistema 96 | Comment[pt_BR]=Calamares — Instalador do sistema 97 | Icon=/etc/calamares/branding/rhino/rhino-calamares.png 98 | Terminal=false 99 | StartupNotify=true 100 | Categories=Qt;System; 101 | Keywords=installer;calamares;system;' | tee -a /usr/share/applications/calamares.desktop >/dev/null 102 | sudo chmod 755 /usr/share/applications/calamares.desktop 103 | sudo cp /usr/share/applications/calamares.desktop /home/rhino-live/Desktop/calamares.desktop 104 | for f in "/usr/share/applications/calamares.desktop" "/home/rhino-live/Desktop/calamares.desktop"; do 105 | gio set -t string "${f}" metadata::xfce-exe-checksum "$(sha256sum ${f} | awk '{print $1}')" 106 | done 107 | sudo chown "rhino-live" -cR /home/rhino-live/Desktop/calamares.desktop 108 | 109 | if [ $(dpkg --print-architecture) = arm64 ]; then 110 | GNU="aarch" 111 | else 112 | GNU="x86_" 113 | fi 114 | 115 | #Lightdm 116 | sudo rm /etc/lightdm/lightdm-gtk-greeter.conf 117 | # TODO: Replace with package. 118 | (cd /etc/lightdm/ && sudo wget https://raw.githubusercontent.com/rhino-linux/lightdm/main/lightdm-gtk-greeter.conf && sudo wget https://github.com/rhino-linux/lightdm/raw/main/rhino-blur.png) 119 | 120 | mkdir /home/rhino-live/.config/autostart/ 121 | 122 | #VSC theme 123 | wget https://ThiagoLcioBittencourt.gallery.vsassets.io/_apis/public/gallery/publisher/ThiagoLcioBittencourt/extension/omni-dracula-theme/1.0.7/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage && mv Microsoft.VisualStudio.Services.VSIXPackage /home/rhino-live/omni-dracula.vsix 124 | sudo chown -cR rhino-live /home/rhino-live/omni-dracula.vsix 125 | sudo mkdir /etc/skel/.config/VSCodium/ 126 | sudo mkdir /etc/skel/.config/VSCodium/User/ 127 | sudo mkdir /home/rhino-live/.config/VSCodium/ 128 | sudo mkdir /home/rhino-live/.config/VSCodium/User/ 129 | sudo chown -cR rhino-live /home/rhino-live/.config/VSCodium/ 130 | HOME=/home/rhino-live runuser -m -u rhino-live -- sh -c 'codium --install-extension /home/rhino-live/omni-dracula.vsix --user-data-dir /etc/skel/.config/VSCodium/ --no-sandbox' 131 | rm /home/rhino-live/omni-dracula.vsix 132 | echo '{ 133 | "workbench.colorTheme": "Omni Dracula Theme" 134 | }' | sudo tee -a /etc/skel/.config/VSCodium/User/settings.json 135 | sudo cp -r /etc/skel/.config/VSCodium/ /home/rhino-live/.config/ 136 | sudo chown -cR rhino-live /home/rhino-live/.config/VSCodium/ 137 | 138 | # The rhino user is created before rhino-linux-xfce4-config is installed, so update their xfce4 configuration 139 | rm -rf /home/rhino-live/.config/xfce4 140 | for i in xfce4 Kvantum plank autostart xfce4 ulauncher cortile gtk-3.0 gtk-4.0; do 141 | mkdir -p /home/rhino-live/.config/${i} 142 | cp -r /etc/skel/.config/${i}/* /home/rhino-live/.config/${i} 143 | done 144 | echo ".-vala-panel-appmenu-core > * { 145 | min-width: 100px; 146 | }" | sudo tee -a /home/rhino-live/.config/gtk-3.0/gtk.css 147 | mkdir /home/rhino-live/.lightpad 148 | cp /etc/skel/.lightpad/* /home/rhino-live/.lightpad 149 | ln -s "/home/rhino-live/.config/xfce4/desktop/icons.screen0-1904x990.rc" "/home/rhino-live/.config/xfce4/desktop/icons.screen.latest.rc" 150 | sudo rm -f /home/rhino-live/.config/autostart/rhino-setup.desktop 151 | sudo rm -f /home/rhino-live/.config/autostart/hello-rhino.desktop 152 | # Make sure the user (rhino) has wrx permissions 153 | chmod -R 777 /home/rhino-live/.config/xfce4 154 | cat >/home/rhino-live/.config/autostart/gsettings.desktop <<__EOF__ 155 | [Desktop Entry] 156 | Encoding=UTF-8 157 | Version=1.0 158 | Type=Application 159 | Name=Gsettings Theme 160 | Comment=Theming for Desktop 161 | Exec=bash -c "gsettings set org.gnome.desktop.interface gtk-theme Adw-dark" 162 | OnlyShowIn=XFCE; 163 | RunHook=0 164 | StartupNotify=false 165 | Terminal=false 166 | Hidden=false 167 | __EOF__ 168 | cat >/home/rhino-live/.config/autostart/calamares_icon.desktop <<__EOF__ 169 | [Desktop Entry] 170 | Encoding=UTF-8 171 | Version=1.0 172 | Type=Application 173 | Name=Calamares Icon Fix 174 | Comment=Set calamares desktop icon as trusted 175 | Exec=bash -c "f=/home/rhino-live/Desktop/calamares.desktop; gio set -t string \${f} metadata::xfce-exe-checksum \$(sha256sum \${f} | awk '{print \$1}')" 176 | done" 177 | OnlyShowIn=XFCE; 178 | RunHook=0 179 | StartupNotify=false 180 | Terminal=false 181 | Hidden=false 182 | __EOF__ 183 | cat >/home/rhino-live/.config/autostart/appmenu.desktop <<__EOF__ 184 | [Desktop Entry] 185 | Encoding=UTF-8 186 | Version=1.0 187 | Type=Application 188 | Name=Appmenu Expand Fix 189 | Comment=Force Appmenu Expand Off 190 | Exec=bash -c "sleep 5; xfconf-query -c xfce4-panel -p /plugins/plugin-6/plugins/plugin-6/expand -s false" 191 | OnlyShowIn=XFCE; 192 | RunHook=0 193 | StartupNotify=false 194 | Terminal=false 195 | Hidden=false 196 | __EOF__ 197 | sudo chown "rhino-live" -cR /home/rhino-live 198 | sudo chown "rhino-live" -cR /home/rhino-live/.config 199 | echo -e "[/home/rhino-live/Desktop/calamares.desktop]\nrow=0\ncol=0\n" >>/home/rhino-live/.config/xfce4/desktop/icons.screen.latest.rc 200 | 201 | echo '[PlankDockItemPreferences] 202 | Launcher=file:///usr/share/applications/calamares.desktop' | tee -a /home/rhino-live/.config/plank/dock1/08-calamares.dockitem >/dev/null 203 | echo "[dock1] 204 | current-workspace-only=false 205 | dock-items=['00-uniLauncher.dockitem', '01-uniApps.dockitem', '02-uniDesktop.dockitem', '03-firefox.dockitem', '04-FileManager.dockitem', '05-codium.dockitem', '06-xfce4-terminal.dockitem', '07-org.rhinolinux.system.dockitem', '08-calamares.dockitem'] 206 | hide-mode='intelligent' 207 | icon-size=48 208 | pinned-only=false 209 | position='left' 210 | pressure-reveal=false 211 | theme='rhinoplank' 212 | zoom-enabled=true 213 | zoom-percent=115" | tee -a /home/rhino-live/.config/docks.ini >/dev/null 214 | 215 | sudo mkdir /etc/skel/.config/Kvantum/ /root/.config/Kvantum/ 216 | 217 | echo '[General] 218 | theme=KvRhinoDark' | tee /root/.config/Kvantum/kvantum.kvconfig /etc/skel/.config/Kvantum/kvantum.kvconfig >/dev/null 219 | 220 | # TODO: This should be seperate from this chroot. 221 | # The Live image user is not removed when instaalled on disk 222 | sudo sed -i '/\/bin\/bash/a userdel rhino-live' /usr/libexec/fixconkeys-part2 223 | 224 | sudo rm /usr/share/lightdm/lightdm.conf.d/60-xubuntu.conf 225 | sudo rm /usr/share/xsessions/xfce.desktop /usr/share/xsessions/xubuntu.desktop 226 | [[ -f /usr/share/backgrounds/xfce/xfce-x.svg ]] && sudo mv /usr/share/backgrounds/xfce/xfce-x.svg /usr/share/backgrounds/xfce/xfce-uglyrat.svg 227 | sudo ln -sf /usr/share/backgrounds/xfce/rolling-rhino-default.png /usr/share/backgrounds/xfce/xfce-x.svg 228 | 229 | # Fix: xubuntu wallpapers overrides ours. 230 | sudo rm /usr/share/xfce4/backdrops/xubuntu-wallpaper.png 231 | sudo ln -sf /usr/share/backgrounds/xfce/rolling-rhino-default.png /usr/share/xfce4/backdrops/xubuntu-wallpaper.png 232 | 233 | sudo apt-get clean 234 | sudo apt-get remove linux*6.17.0* -yq 235 | sudo update-initramfs -u 236 | -------------------------------------------------------------------------------- /etc/config/includes.chroot/usr/lib/python3/dist-packages/lsb_release.py: -------------------------------------------------------------------------------- 1 | # LSB release detection module for Debian 2 | # (C) 2005-10 Chris Lawrence 3 | # (C) 2018 Didier Raboud 4 | 5 | # This package is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; version 2 dated June, 1991. 8 | 9 | # This package is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | 14 | # You should have received a copy of the GNU General Public License 15 | # along with this package; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | # 02110-1301 USA 18 | 19 | import sys 20 | import subprocess 21 | import os 22 | import re 23 | import warnings 24 | import csv 25 | 26 | def get_distro_info(origin='Debian'): 27 | 28 | try: 29 | csvfile = open('/usr/share/distro-info/%s.csv' % origin.lower()) 30 | except FileNotFoundError: 31 | # Unknown distro, fallback to Debian 32 | csvfile = open('/usr/share/distro-info/debian.csv') 33 | 34 | reader = csv.DictReader(csvfile) 35 | global RELEASE_CODENAME_LOOKUP, RELEASES_ORDER, TESTING_CODENAME 36 | RELEASE_CODENAME_LOOKUP = { r['version']: r['series'] for r in reader if r['version']} 37 | RELEASES_ORDER = list(RELEASE_CODENAME_LOOKUP.items()) 38 | RELEASES_ORDER.sort(key=lambda n: [int(v) for v in re.split('\D+', n[0]) if v.isdigit()]) 39 | RELEASES_ORDER = list(list(zip(*RELEASES_ORDER))[1]) 40 | 41 | if origin.lower() == 'debian': 42 | TESTING_CODENAME = 'unknown.new.testing' 43 | RELEASES_ORDER.extend(['stable', 'proposed-updates', 'testing', 'testing-proposed-updates', 'unstable', 'sid']) 44 | 45 | csvfile.close() 46 | 47 | # Populate default distro info 48 | get_distro_info() 49 | 50 | def lookup_codename(release, unknown=None): 51 | m = re.match(r'(\d+)\.(\d+)(r(\d+))?', release) 52 | if not m: 53 | return unknown 54 | 55 | if int(m.group(1)) < 7: 56 | shortrelease = '%s.%s' % m.group(1,2) 57 | else: 58 | shortrelease = '%s' % m.group(1) 59 | return RELEASE_CODENAME_LOOKUP.get(shortrelease, unknown) 60 | 61 | # LSB compliance packages... may grow eventually 62 | PACKAGES = 'lsb-core lsb-cxx lsb-graphics lsb-desktop lsb-languages lsb-multimedia lsb-printing lsb-security' 63 | 64 | modnamere = re.compile(r'lsb-(?P[a-z0-9]+)-(?P[^ ]+)(?: \(= (?P[0-9.]+)\))?') 65 | 66 | def valid_lsb_versions(version, module): 67 | # If a module is ever released that only appears in >= version, deal 68 | # with that here 69 | if version == '3.0': 70 | return ['2.0', '3.0'] 71 | elif version == '3.1': 72 | if module in ('desktop', 'qt4'): 73 | return ['3.1'] 74 | elif module == 'cxx': 75 | return ['3.0', '3.1'] 76 | else: 77 | return ['2.0', '3.0', '3.1'] 78 | elif version == '3.2': 79 | if module == 'desktop': 80 | return ['3.1', '3.2'] 81 | elif module == 'qt4': 82 | return ['3.1'] 83 | elif module in ('printing', 'languages', 'multimedia'): 84 | return ['3.2'] 85 | elif module == 'cxx': 86 | return ['3.0', '3.1', '3.2'] 87 | else: 88 | return ['2.0', '3.0', '3.1', '3.2'] 89 | elif version == '4.0': 90 | if module == 'desktop': 91 | return ['3.1', '3.2', '4.0'] 92 | elif module == 'qt4': 93 | return ['3.1'] 94 | elif module in ('printing', 'languages', 'multimedia'): 95 | return ['3.2', '4.0'] 96 | elif module == 'security': 97 | return ['4.0'] 98 | elif module == 'cxx': 99 | return ['3.0', '3.1', '3.2', '4.0'] 100 | else: 101 | return ['2.0', '3.0', '3.1', '3.2', '4.0'] 102 | elif version == '4.1': 103 | if module == 'desktop': 104 | return ['3.1', '3.2', '4.0', '4.1'] 105 | elif module == 'qt4': 106 | return ['3.1'] 107 | elif module in ('printing', 'languages', 'multimedia'): 108 | return ['3.2', '4.0', '4.1'] 109 | elif module == 'security': 110 | return ['4.0', '4.1'] 111 | elif module == 'cxx': 112 | return ['3.0', '3.1', '3.2', '4.0', '4.1'] 113 | else: 114 | return ['2.0', '3.0', '3.1', '3.2', '4.0', '4.1'] 115 | 116 | 117 | return [version] 118 | 119 | try: 120 | set # introduced in 2.4 121 | except NameError: 122 | import sets 123 | set = sets.Set 124 | 125 | # This is Debian-specific at present 126 | def check_modules_installed(): 127 | # Find which LSB modules are installed on this system 128 | C_env = os.environ.copy(); C_env['LC_ALL'] = 'C' 129 | output = subprocess.Popen(['dpkg-query','-f',"${Version} ${Provides}\n",'-W'] + PACKAGES.split(), 130 | env=C_env, 131 | stdout=subprocess.PIPE, 132 | stderr=subprocess.PIPE, 133 | close_fds=True).communicate()[0].decode('utf-8') 134 | 135 | if not output: 136 | return [] 137 | 138 | modules = set() 139 | for line in output.split(os.linesep): 140 | if not line: 141 | break 142 | version, provides = line.split(' ', 1) 143 | # Debian package versions can be 3.2-$REV, 3.2+$REV or 3.2~$REV. 144 | version = re.split('[-+~]', version, 1)[0] 145 | for pkg in provides.split(','): 146 | mob = modnamere.search(pkg) 147 | if not mob: 148 | continue 149 | 150 | mgroups = mob.groupdict() 151 | # If no versioned provides... 152 | if mgroups.get('version'): 153 | module = '%(module)s-%(version)s-%(arch)s' % mgroups 154 | modules.add(module) 155 | else: 156 | module = mgroups['module'] 157 | for v in valid_lsb_versions(version, module): 158 | mgroups['version'] = v 159 | module = '%(module)s-%(version)s-%(arch)s' % mgroups 160 | modules.add(module) 161 | 162 | modules = list(modules) 163 | modules.sort() 164 | return modules 165 | 166 | longnames = {'v' : 'version', 'o': 'origin', 'a': 'suite', 167 | 'c' : 'component', 'l': 'label'} 168 | 169 | def parse_policy_line(data): 170 | retval = {} 171 | bits = data.split(',') 172 | for bit in bits: 173 | kv = bit.split('=', 1) 174 | if len(kv) > 1: 175 | k, v = kv[:2] 176 | if k in longnames: 177 | retval[longnames[k]] = v 178 | return retval 179 | 180 | def release_index(x): 181 | suite = x[1].get('suite') 182 | if suite: 183 | if suite in RELEASES_ORDER: 184 | return int(len(RELEASES_ORDER) - RELEASES_ORDER.index(suite)) 185 | else: 186 | try: 187 | return float(suite) 188 | except ValueError: 189 | return 0 190 | return 0 191 | 192 | def compare_release(x, y): 193 | warnings.warn('compare_release(x,y) is deprecated; please use the release_index(x) as key for sort() instead.', DeprecationWarning, stacklevel=2) 194 | suite_x_i = release_index(x) 195 | suite_y_i = release_index(y) 196 | 197 | try: 198 | return suite_x_i - suite_y_i 199 | except TypeError: 200 | return (suite_x_i > suite_y_i) - (suite_x_i < suite_y_i) 201 | 202 | def parse_apt_policy(): 203 | data = [] 204 | 205 | C_env = os.environ.copy(); C_env['LC_ALL'] = 'C.UTF-8' 206 | try: 207 | policy = subprocess.Popen(['apt-cache','policy'], 208 | env=C_env, 209 | stdout=subprocess.PIPE, 210 | stderr=subprocess.PIPE, 211 | close_fds=True).communicate()[0].decode('utf-8') 212 | except Exception as e: 213 | print('Failed to run apt-cache:', e, file=sys.stderr) 214 | return 215 | 216 | for line in policy.split('\n'): 217 | line = line.strip() 218 | m = re.match(r'(-?\d+)', line) 219 | if m: 220 | priority = int(m.group(1)) 221 | if line.startswith('release'): 222 | bits = line.split(' ', 1) 223 | if len(bits) > 1: 224 | data.append( (priority, parse_policy_line(bits[1])) ) 225 | 226 | return data 227 | 228 | def guess_release_from_apt(origin='Debian', component='main', 229 | ignoresuites=('experimental'), 230 | label='Debian', 231 | alternate_olabels={'Debian Ports': ('ftp.ports.debian.org', 'ftp.debian-ports.org')}): 232 | releases = parse_apt_policy() 233 | 234 | if not releases: 235 | return None 236 | 237 | # We only care about the specified origin, component, and label 238 | releases = [x for x in releases if ( 239 | x[1].get('origin', '') == origin and 240 | x[1].get('suite', '') not in ignoresuites and 241 | x[1].get('component', '') == component and 242 | x[1].get('label', '') == label) or ( 243 | x[1].get('origin', '') in alternate_olabels and 244 | x[1].get('label', '') in alternate_olabels.get(x[1].get('origin', '')))] 245 | 246 | # Check again to make sure we didn't wipe out all of the releases 247 | if not releases: 248 | return None 249 | 250 | releases.sort(key=lambda tuple: tuple[0],reverse=True) 251 | 252 | # We've sorted the list by descending priority, so the first entry should 253 | # be the "main" release in use on the system 254 | 255 | max_priority = releases[0][0] 256 | releases = [x for x in releases if x[0] == max_priority] 257 | releases.sort(key=release_index) 258 | 259 | return releases[0][1] 260 | 261 | def guess_debian_release(): 262 | distinfo = {} 263 | 264 | distinfo['ID'] = 'Debian' 265 | # Use /etc/dpkg/origins/default to fetch the distribution name 266 | etc_dpkg_origins_default = os.environ.get('LSB_ETC_DPKG_ORIGINS_DEFAULT','/etc/dpkg/origins/default') 267 | if os.path.exists(etc_dpkg_origins_default): 268 | try: 269 | with open(etc_dpkg_origins_default) as dpkg_origins_file: 270 | for line in dpkg_origins_file: 271 | try: 272 | (header, content) = line.split(': ', 1) 273 | header = header.lower() 274 | content = content.strip() 275 | if header == 'vendor': 276 | distinfo['ID'] = content 277 | except ValueError: 278 | pass 279 | except IOError as msg: 280 | print('Unable to open ' + etc_dpkg_origins_default + ':', str(msg), file=sys.stderr) 281 | 282 | # Populate RELEASES_ORDER for the correct distro 283 | get_distro_info(distinfo['ID']) 284 | 285 | kern = os.uname()[0] 286 | if kern in ('Linux', 'Hurd', 'NetBSD'): 287 | distinfo['OS'] = 'GNU/'+kern 288 | elif kern == 'FreeBSD': 289 | distinfo['OS'] = 'GNU/k'+kern 290 | elif kern in ('GNU/Linux', 'GNU/kFreeBSD'): 291 | distinfo['OS'] = kern 292 | else: 293 | distinfo['OS'] = 'GNU' 294 | 295 | distinfo['DESCRIPTION'] = '%(ID)s %(OS)s' % distinfo 296 | 297 | etc_debian_version = os.environ.get('LSB_ETC_DEBIAN_VERSION','/etc/debian_version') 298 | if os.path.exists(etc_debian_version): 299 | try: 300 | with open(etc_debian_version) as debian_version: 301 | release = debian_version.read().strip() 302 | except IOError as msg: 303 | print('Unable to open ' + etc_debian_version + ':', str(msg), file=sys.stderr) 304 | release = 'unknown' 305 | 306 | if not release[0:1].isalpha(): 307 | # /etc/debian_version should be numeric 308 | codename = lookup_codename(release, 'n/a') 309 | distinfo.update({ 'RELEASE' : release, 'CODENAME' : codename }) 310 | elif release.endswith('/sid'): 311 | if release.rstrip('/sid').lower() != 'testing': 312 | global TESTING_CODENAME 313 | TESTING_CODENAME = release.rstrip('/sid') 314 | distinfo['RELEASE'] = 'testing/unstable' 315 | else: 316 | distinfo['RELEASE'] = release 317 | 318 | # Only use apt information if we did not get the proper information 319 | # from /etc/debian_version or if we don't have a codename 320 | # (which will happen if /etc/debian_version does not contain a 321 | # number but some text like 'testing/unstable' or 'lenny/sid') 322 | # 323 | # This is slightly faster and less error prone in case the user 324 | # has an entry in his /etc/apt/sources.list but has not actually 325 | # upgraded the system. 326 | if not distinfo.get('CODENAME'): 327 | rinfo = guess_release_from_apt() 328 | if rinfo: 329 | release = rinfo.get('version') 330 | 331 | # Special case Debian-Ports as their Release file has 'version': '1.0' 332 | if release == '1.0' and rinfo.get('origin') == 'Debian Ports' and rinfo.get('label') in ('ftp.ports.debian.org', 'ftp.debian-ports.org'): 333 | release = None 334 | rinfo.update({'suite': 'unstable'}) 335 | 336 | if release: 337 | codename = lookup_codename(release, 'n/a') 338 | else: 339 | release = rinfo.get('suite', 'unstable') 340 | if release == 'testing': 341 | # Would be nice if I didn't have to hardcode this. 342 | codename = TESTING_CODENAME 343 | else: 344 | codename = 'sid' 345 | distinfo.update({ 'RELEASE' : release, 'CODENAME' : codename }) 346 | 347 | if distinfo.get('RELEASE'): 348 | distinfo['DESCRIPTION'] += ' %(RELEASE)s' % distinfo 349 | if distinfo.get('CODENAME'): 350 | distinfo['DESCRIPTION'] += ' (%(CODENAME)s)' % distinfo 351 | 352 | return distinfo 353 | 354 | # Whatever is guessed above can be overridden in /usr/lib/os-release by derivatives 355 | def get_os_release(): 356 | distinfo = {} 357 | os_release = os.environ.get('LSB_OS_RELEASE', '/usr/lib/os-release') 358 | if os.path.exists(os_release): 359 | try: 360 | with open(os_release) as os_release_file: 361 | for line in os_release_file: 362 | line = line.strip() 363 | if not line: 364 | continue 365 | # Skip invalid lines 366 | if not '=' in line: 367 | continue 368 | var, arg = line.split('=', 1) 369 | if arg.startswith('"') and arg.endswith('"'): 370 | arg = arg[1:-1] 371 | if arg: # Ignore empty arguments 372 | # Concert os-release to lsb-release-style 373 | if var == 'VERSION_ID': 374 | # It'll ignore point-releases 375 | distinfo['RELEASE'] = arg.strip() 376 | elif var == 'VERSION_CODENAME': 377 | distinfo['CODENAME'] = arg.strip() 378 | elif var == 'ID': 379 | # ID=debian 380 | distinfo['ID'] = arg.strip().title() 381 | elif var == 'PRETTY_NAME': 382 | distinfo['DESCRIPTION'] = arg.strip() 383 | except IOError as msg: 384 | print('Unable to open ' + os_release + ':', str(msg), file=sys.stderr) 385 | 386 | return distinfo 387 | 388 | def get_distro_information(): 389 | lsbinfo = get_os_release() 390 | # OS is only used inside guess_debian_release anyway 391 | for key in ('ID', 'RELEASE', 'CODENAME', 'DESCRIPTION',): 392 | if key not in lsbinfo: 393 | distinfo = guess_debian_release() 394 | distinfo.update(lsbinfo) 395 | return distinfo 396 | else: 397 | return lsbinfo 398 | 399 | def test(): 400 | print(get_distro_information()) 401 | print(check_modules_installed()) 402 | 403 | if __name__ == '__main__': 404 | test() 405 | -------------------------------------------------------------------------------- /.github/workflows/legacy.yml: -------------------------------------------------------------------------------- 1 | name: Rhino Linux Image Generation (Meta) [Legacy Workflow] 2 | 3 | on: 4 | workflow_dispatch 5 | 6 | jobs: 7 | build_amd64: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | submodules: recursive 13 | 14 | - name: Install needed packages 15 | run: | 16 | sudo rm -rf /var/lib/apt/lists/* 17 | sudo apt-get update && sudo apt-get install --reinstall debootstrap mtools dosfstools qemu-user-static binfmt-support dpkg-dev -y 18 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/noble 19 | sudo dpkg -i debs/live-build_*_all.deb 20 | sudo mv /usr/share/debootstrap/functions functions 21 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 22 | sudo mv functions /usr/share/debootstrap/functions 23 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 24 | 25 | - name: Make scripts executable 26 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 27 | 28 | - name: Build ISO 29 | run: | 30 | sudo ./build.sh etc/terraform.conf 31 | echo "ISOX64=$(cd builds/amd64; ls *.iso)" >> $GITHUB_ENV 32 | 33 | - uses: actions/upload-artifact@v4.3.3 34 | with: 35 | name: ${{ env.ISOX64 }} 36 | path: builds/amd64/${{ env.ISOX64 }} 37 | 38 | build_arm64: 39 | runs-on: ubuntu-24.04-arm 40 | steps: 41 | - uses: actions/checkout@v4 42 | with: 43 | submodules: recursive 44 | 45 | - name: Install needed packages 46 | run: | 47 | sudo rm -rf /var/lib/apt/lists/* 48 | sudo apt-get update && sudo apt-get install --reinstall debootstrap mtools dosfstools qemu-user-static binfmt-support dpkg-dev -y 49 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/noble 50 | sudo dpkg -i debs/live-build_*_all.deb 51 | sudo mv /usr/share/debootstrap/functions functions 52 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 53 | sudo mv functions /usr/share/debootstrap/functions 54 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 55 | 56 | - name: Make scripts executable 57 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 58 | 59 | - name: Build ISO 60 | run: | 61 | sudo ./build.sh etc/terraform.conf 62 | echo "ISOA64=$(cd builds/arm64; ls *.iso)" >> $GITHUB_ENV 63 | 64 | - uses: actions/upload-artifact@v4.3.3 65 | with: 66 | name: ${{ env.ISOA64 }} 67 | path: builds/arm64/${{ env.ISOA64 }} 68 | 69 | build_pine_tarball: 70 | runs-on: ubuntu-24.04-arm 71 | steps: 72 | - uses: actions/checkout@v4 73 | with: 74 | ref: 'pinephone' 75 | 76 | - name: Install needed packages 77 | run: | 78 | sudo rm -rf /etc/apt/sources.list.d/microsoft-prod.list 79 | sudo rm -rf /var/lib/apt/lists/* 80 | sudo apt-get update && sudo apt-get install debootstrap mtools dosfstools qemu-user-static binfmt-support dpkg-dev -y 81 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/noble 82 | sudo dpkg -i debs/live-build_*_all.deb 83 | sudo mv /usr/share/debootstrap/functions functions 84 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 85 | sudo mv functions /usr/share/debootstrap/functions 86 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 87 | sudo cp binary_rootfs /usr/lib/live/build/binary_rootfs 88 | 89 | - name: Make scripts executable 90 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 91 | 92 | - name: Build tarball 93 | run: sudo ./build.sh etc/terraform.conf 94 | 95 | - uses: actions/cache@v4 96 | with: 97 | path: binary/ 98 | key: tar-pine-${{ github.run_id }} 99 | 100 | deploy_pine: 101 | needs: build_pine_tarball 102 | runs-on: ubuntu-latest 103 | steps: 104 | - uses: actions/checkout@v4 105 | with: 106 | ref: 'pinephone' 107 | 108 | - uses: actions/cache@v4 109 | with: 110 | path: binary/ 111 | key: tar-pine-${{ github.run_id }} 112 | 113 | - name: Deploy to partition 114 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-pinephone.img" -m 10G pinephone.yaml 115 | 116 | - name: Place output folder 117 | run: sudo mkdir -p builds/pine 118 | 119 | - name: Move to output folder and compress 120 | run: | 121 | sudo mv Rhino*pinephone.img builds/pine/ 122 | sudo xz -v builds/pine/Rhino*pinephone.img 123 | echo "IMGPP=$(cd builds/pine; ls *.img.xz)" >> $GITHUB_ENV 124 | 125 | - uses: actions/upload-artifact@v4.3.3 126 | with: 127 | name: ${{ env.IMGPP }} 128 | path: builds/pine/${{ env.IMGPP }} 129 | 130 | deploy_pinepro: 131 | needs: build_pine_tarball 132 | runs-on: ubuntu-latest 133 | steps: 134 | - uses: actions/checkout@v4 135 | with: 136 | ref: 'pinephone' 137 | 138 | - uses: actions/cache@v4 139 | with: 140 | path: binary/ 141 | key: tar-pine-${{ github.run_id }} 142 | 143 | - name: Deploy to partition 144 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-pinephonepro.img" -m 10G pinephonepro.yaml 145 | 146 | - name: Place output folder 147 | run: sudo mkdir -p builds/pinepro 148 | 149 | - name: Move to output folder and compress 150 | run: | 151 | sudo mv Rhino*pinephonepro.img builds/pinepro/ 152 | sudo xz -v builds/pinepro/Rhino*pinephonepro.img 153 | echo "IMGPPP=$(cd builds/pinepro; ls *.img.xz)" >> $GITHUB_ENV 154 | 155 | - uses: actions/upload-artifact@v4.3.3 156 | with: 157 | name: ${{ env.IMGPPP }} 158 | path: builds/pinepro/${{ env.IMGPPP }} 159 | 160 | build_rpi_tarball: 161 | runs-on: ubuntu-24.04-arm 162 | steps: 163 | - uses: actions/checkout@v4 164 | with: 165 | ref: 'rpi' 166 | 167 | - name: Install needed packages 168 | run: | 169 | sudo rm -rf /etc/apt/sources.list.d/microsoft-prod.list 170 | sudo rm -rf /var/lib/apt/lists/* 171 | sudo apt-get update && sudo apt-get install debootstrap mtools dosfstools qemu-user-static binfmt-support dpkg-dev -y 172 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/noble 173 | sudo dpkg -i debs/live-build_*_all.deb 174 | sudo mv /usr/share/debootstrap/functions functions 175 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 176 | sudo mv functions /usr/share/debootstrap/functions 177 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 178 | 179 | - name: Make scripts executable 180 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 181 | 182 | - name: Build tarball 183 | run: sudo ./build.sh etc/terraform.conf 184 | 185 | - uses: actions/cache@v4 186 | with: 187 | path: binary/ 188 | key: tar-rpi-${{ github.run_id }} 189 | 190 | deploy_rpi_desktop: 191 | needs: build_rpi_tarball 192 | runs-on: ubuntu-latest 193 | steps: 194 | - uses: actions/checkout@v4 195 | with: 196 | ref: 'rpi' 197 | 198 | - uses: actions/cache@v4 199 | with: 200 | path: binary/ 201 | key: tar-rpi-${{ github.run_id }} 202 | 203 | - name: Deploy to partition 204 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-rpi-desktop.img" -m 10G raspberrypi-desktop.yaml 205 | 206 | - name: Place output folder 207 | run: sudo mkdir -p builds/rpi-desktop 208 | 209 | - name: Move to output folder and compress 210 | run: | 211 | sudo mv Rhino*rpi-desktop.img builds/rpi-desktop/ 212 | sudo xz -v builds/rpi-desktop/Rhino*rpi-desktop.img 213 | echo "IMGRPD=$(cd builds/rpi-desktop; ls *.img.xz)" >> $GITHUB_ENV 214 | 215 | - uses: actions/upload-artifact@v4.3.3 216 | with: 217 | name: ${{ env.IMGRPD }} 218 | path: builds/rpi-desktop/${{ env.IMGRPD }} 219 | 220 | deploy_rpi_server: 221 | needs: build_rpi_tarball 222 | runs-on: ubuntu-latest 223 | steps: 224 | - uses: actions/checkout@v4 225 | with: 226 | ref: 'rpi' 227 | 228 | - uses: actions/cache@v4 229 | with: 230 | path: binary/ 231 | key: tar-rpi-${{ github.run_id }} 232 | 233 | - name: Deploy to partition 234 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-rpi-server.img" -m 10G raspberrypi-server.yaml 235 | 236 | - name: Place output folder 237 | run: sudo mkdir -p builds/rpi-server 238 | 239 | - name: Move to output folder and compress 240 | run: | 241 | sudo mv Rhino*rpi-server.img builds/rpi-server/ 242 | sudo xz -v builds/rpi-server/Rhino*rpi-server.img 243 | echo "IMGRPS=$(cd builds/rpi-server; ls *.img.xz)" >> $GITHUB_ENV 244 | 245 | - uses: actions/upload-artifact@v4.3.3 246 | with: 247 | name: ${{ env.IMGRPS }} 248 | path: builds/rpi-server/${{ env.IMGRPS }} 249 | 250 | build_tab_tarball: 251 | runs-on: ubuntu-24.04-arm 252 | steps: 253 | - uses: actions/checkout@v4 254 | with: 255 | ref: 'pinetab' 256 | 257 | - name: Install needed packages 258 | run: | 259 | sudo rm -rf /etc/apt/sources.list.d/microsoft-prod.list 260 | sudo rm -rf /var/lib/apt/lists/* 261 | sudo apt-get update && sudo apt-get install debootstrap mtools dosfstools qemu-user-static binfmt-support dpkg-dev -y 262 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/noble 263 | sudo dpkg -i debs/live-build_*_all.deb 264 | sudo mv /usr/share/debootstrap/functions functions 265 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 266 | sudo mv functions /usr/share/debootstrap/functions 267 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 268 | sudo cp binary_rootfs /usr/lib/live/build/binary_rootfs 269 | 270 | - name: Make scripts executable 271 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 272 | 273 | - name: Build tarball 274 | run: sudo ./build.sh etc/terraform.conf 275 | 276 | - uses: actions/cache@v4 277 | with: 278 | path: binary/ 279 | key: tar-tab-${{ github.run_id }} 280 | 281 | deploy_tab1: 282 | needs: build_tab_tarball 283 | runs-on: ubuntu-latest 284 | steps: 285 | - uses: actions/checkout@v4 286 | with: 287 | ref: 'pinetab' 288 | 289 | - uses: actions/cache@v4 290 | with: 291 | path: binary/ 292 | key: tar-tab-${{ github.run_id }} 293 | 294 | - name: Deploy to partition 295 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-pinetab.img" -m 10G pinetab.yaml 296 | 297 | - name: Place output folder 298 | run: sudo mkdir -p builds/tab 299 | 300 | - name: Move to output folder and compress 301 | run: | 302 | sudo mv Rhino*tab.img builds/tab/ 303 | sudo xz -v builds/tab/Rhino*tab.img 304 | echo "IMGPTA=$(cd builds/tab; ls *.img.xz)" >> $GITHUB_ENV 305 | 306 | - uses: actions/upload-artifact@v4.3.3 307 | with: 308 | name: ${{ env.IMGPTA }} 309 | path: builds/tab/${{ env.IMGPTA }} 310 | 311 | deploy_tab2: 312 | needs: build_tab_tarball 313 | runs-on: ubuntu-latest 314 | steps: 315 | - uses: actions/checkout@v4 316 | with: 317 | ref: 'pinetab' 318 | 319 | - uses: actions/cache@v4 320 | with: 321 | path: binary/ 322 | key: tar-tab-${{ github.run_id }} 323 | 324 | - name: Deploy to partition 325 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-pinetab2.img" -m 10G pinetab2.yaml 326 | 327 | - name: Place output folder 328 | run: sudo mkdir -p builds/tab2 329 | 330 | - name: Move to output folder and compress 331 | run: | 332 | sudo mv Rhino*tab2.img builds/tab2/ 333 | sudo xz -v builds/tab2/Rhino*tab2.img 334 | echo "IMGPTB=$(cd builds/tab2; ls *.img.xz)" >> $GITHUB_ENV 335 | 336 | - uses: actions/upload-artifact@v4.3.3 337 | with: 338 | name: ${{ env.IMGPTB }} 339 | path: builds/tab2/${{ env.IMGPTB }} 340 | 341 | build_pine_lomiri_tarball: 342 | runs-on: ubuntu-24.04-arm 343 | steps: 344 | - uses: actions/checkout@v4 345 | with: 346 | ref: 'pinephone-lomiri' 347 | 348 | - name: Install needed packages 349 | run: | 350 | sudo rm -rf /etc/apt/sources.list.d/microsoft-prod.list 351 | sudo rm -rf /var/lib/apt/lists/* 352 | sudo apt-get update && sudo apt-get install debootstrap mtools dosfstools qemu-user-static binfmt-support dpkg-dev -y 353 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/noble 354 | sudo dpkg -i debs/live-build_*_all.deb 355 | sudo mv /usr/share/debootstrap/functions functions 356 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 357 | sudo mv functions /usr/share/debootstrap/functions 358 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 359 | sudo cp binary_rootfs /usr/lib/live/build/binary_rootfs 360 | 361 | - name: Make scripts executable 362 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 363 | 364 | - name: Build tarball 365 | run: sudo ./build.sh etc/terraform.conf 366 | 367 | - uses: actions/cache@v4 368 | with: 369 | path: binary/ 370 | key: tar-pine-lomiri-${{ github.run_id }} 371 | 372 | deploy_pine_lomiri: 373 | needs: build_pine_lomiri_tarball 374 | runs-on: ubuntu-latest 375 | steps: 376 | - uses: actions/checkout@v4 377 | with: 378 | ref: 'pinephone-lomiri' 379 | 380 | - uses: actions/cache@v4 381 | with: 382 | path: binary/ 383 | key: tar-pine-lomiri-${{ github.run_id }} 384 | 385 | - name: Deploy to partition 386 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-pinephone-lomiri.img" -m 10G pinephone.yaml 387 | 388 | - name: Place output folder 389 | run: sudo mkdir -p builds/pine-lomiri 390 | 391 | - name: Move to output folder and compress 392 | run: | 393 | sudo mv Rhino*pinephone-lomiri.img builds/pine-lomiri/ 394 | sudo xz -v builds/pine-lomiri/Rhino*pinephone-lomiri.img 395 | echo "IMGPPL=$(cd builds/pine-lomiri; ls *.img.xz)" >> $GITHUB_ENV 396 | 397 | - uses: actions/upload-artifact@v4.3.3 398 | with: 399 | name: ${{ env.IMGPPL }} 400 | path: builds/pine-lomiri/${{ env.IMGPPL }} 401 | 402 | 403 | deploy_pinepro_lomiri: 404 | needs: build_pine_lomiri_tarball 405 | runs-on: ubuntu-latest 406 | steps: 407 | - uses: actions/checkout@v4 408 | with: 409 | ref: 'pinephone-lomiri' 410 | 411 | - uses: actions/cache@v4 412 | with: 413 | path: binary/ 414 | key: tar-pine-lomiri-${{ github.run_id }} 415 | 416 | - name: Deploy to partition 417 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-pinephonepro-lomiri.img" -m 10G pinephonepro.yaml 418 | 419 | - name: Place output folder 420 | run: sudo mkdir -p builds/pinepro-lomiri 421 | 422 | - name: Move to output folder and compress 423 | run: | 424 | sudo mv Rhino*pinephonepro-lomiri.img builds/pinepro-lomiri/ 425 | sudo xz -v builds/pinepro-lomiri/Rhino*pinephonepro-lomiri.img 426 | echo "IMGPPPL=$(cd builds/pinepro-lomiri; ls *.img.xz)" >> $GITHUB_ENV 427 | 428 | - uses: actions/upload-artifact@v4.3.3 429 | with: 430 | name: ${{ env.IMGPPPL }} 431 | path: builds/pinepro-lomiri/${{ env.IMGPPPL }} 432 | 433 | build_tab_lomiri_tarball: 434 | runs-on: ubuntu-24.04-arm 435 | steps: 436 | - uses: actions/checkout@v4 437 | with: 438 | ref: 'pinetab-lomiri' 439 | 440 | - name: Install needed packages 441 | run: | 442 | sudo rm -rf /etc/apt/sources.list.d/microsoft-prod.list 443 | sudo rm -rf /var/lib/apt/lists/* 444 | sudo apt-get update && sudo apt-get install debootstrap mtools dosfstools qemu-user-static binfmt-support dpkg-dev -y 445 | sudo ln -sfn /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/noble 446 | sudo dpkg -i debs/live-build_*_all.deb 447 | sudo mv /usr/share/debootstrap/functions functions 448 | sudo patch -i 0002-remove-WRONGSUITE-error.patch 449 | sudo mv functions /usr/share/debootstrap/functions 450 | sudo cp binary_grub-efi /usr/lib/live/build/binary_grub-efi 451 | sudo cp binary_rootfs /usr/lib/live/build/binary_rootfs 452 | 453 | - name: Make scripts executable 454 | run: chmod -R +x build.sh etc/auto/config etc/terraform.conf etc/ 455 | 456 | - name: Build tarball 457 | run: sudo ./build.sh etc/terraform.conf 458 | 459 | - uses: actions/cache@v4 460 | with: 461 | path: binary/ 462 | key: tar-tab-lomiri-${{ github.run_id }} 463 | 464 | deploy_tab1_lomiri: 465 | needs: build_tab_lomiri_tarball 466 | runs-on: ubuntu-latest 467 | steps: 468 | - uses: actions/checkout@v4 469 | with: 470 | ref: 'pinetab-lomiri' 471 | 472 | - uses: actions/cache@v4 473 | with: 474 | path: binary/ 475 | key: tar-tab-lomiri-${{ github.run_id }} 476 | 477 | - name: Deploy to partition 478 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-pinetab-lomiri.img" -m 10G pinetab.yaml 479 | 480 | - name: Place output folder 481 | run: sudo mkdir -p builds/tab-lomiri 482 | 483 | - name: Move to output folder and compress 484 | run: | 485 | sudo mv Rhino*tab-lomiri.img builds/tab-lomiri/ 486 | sudo xz -v builds/tab-lomiri/Rhino*tab-lomiri.img 487 | echo "IMGPTAL=$(cd builds/tab-lomiri; ls *.img.xz)" >> $GITHUB_ENV 488 | 489 | - uses: actions/upload-artifact@v4.3.3 490 | with: 491 | name: ${{ env.IMGPTAL }} 492 | path: builds/tab-lomiri/${{ env.IMGPTAL }} 493 | 494 | deploy_tab2_lomiri: 495 | needs: build_tab_lomiri_tarball 496 | runs-on: ubuntu-latest 497 | steps: 498 | - uses: actions/checkout@v4 499 | with: 500 | ref: 'pinetab-lomiri' 501 | 502 | - uses: actions/cache@v4 503 | with: 504 | path: binary/ 505 | key: tar-tab-lomiri-${{ github.run_id }} 506 | 507 | - name: Deploy to partition 508 | run: source ./etc/terraform.conf && VER="${VERSION}${SUBVER}" && sudo ./debos-docker -t image:"Rhino-Linux-${VER}-pinetab2-lomiri.img" -m 10G pinetab2.yaml 509 | 510 | - name: Place output folder 511 | run: sudo mkdir -p builds/tab2-lomiri 512 | 513 | - name: Move to output folder and compress 514 | run: | 515 | sudo mv Rhino*tab2-lomiri.img builds/tab2-lomiri/ 516 | sudo xz -v builds/tab2-lomiri/Rhino*tab2-lomiri.img 517 | echo "IMGPTBL=$(cd builds/tab2-lomiri; ls *.img.xz)" >> $GITHUB_ENV 518 | 519 | - uses: actions/upload-artifact@v4.3.3 520 | with: 521 | name: ${{ env.IMGPTBL }} 522 | path: builds/tab2-lomiri/${{ env.IMGPTBL }} 523 | -------------------------------------------------------------------------------- /ub2r.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | declare -gx PS4=$'\E[0;10m\E[1m\033[1;31m\033[1;37m[\033[1;35m${BASH_SOURCE[0]##*/}:\033[1;34m${FUNCNAME[0]:-NOFUNC}():\033[1;33m${LINENO}\033[1;37m] - \033[1;33mDEBUG: \E[0;10m' 4 | shopt -s extglob 5 | 6 | # Colors 7 | if [[ -z $NO_COLOR ]]; then 8 | RED=$'\033[0;31m' 9 | GREEN=$'\033[0;32m' 10 | YELLOW=$'\033[0;33m' 11 | BLUE=$'\033[0;34m' 12 | PURPLE=$'\033[0;35m' 13 | CYAN=$'\033[0;36m' 14 | WHITE=$'\033[0;37m' 15 | BGreen=$'\033[1;32m' 16 | BCyan=$'\033[1;36m' 17 | BYellow=$'\033[1;33m' 18 | BBlue=$'\033[1;34m' 19 | BPurple=$'\033[1;35m' 20 | BRed=$'\033[1;31m' 21 | BWhite=$'\033[1;37m' 22 | NC=$'\033[0m' 23 | BOLD=$'\033[1m' 24 | UBORANGE=$'\e[38;5;166m' 25 | RLPURPLE=$'\e[38;5;104m' 26 | RMPURPLE=$'\e[38;5;98m' 27 | RDPURPLE=$'\e[38;5;55m' 28 | BUbOrange=$'\e[1m\e[38;5;166m' 29 | BRlPurple=$'\e[1m\e[38;5;104m' 30 | BRmPurple=$'\e[1m\e[38;5;98m' 31 | BRdPurple=$'\e[1m\e[38;5;55m' 32 | fi 33 | 34 | function echo_repo_config() { 35 | local uri_source="$1" suite="$2" sec="$3" selected_uri_dir="ubuntu" architectures 36 | case "$uri_source" in 37 | ports) 38 | selected_uri_source="ports" 39 | architectures="amd64 i386" 40 | selected_uri_dir="ubuntu-ports" 41 | ;; 42 | archive) 43 | selected_uri_source="archive" 44 | architectures="arm64" 45 | ;; 46 | security) 47 | selected_uri_source="security" 48 | architectures="arm64" 49 | ;; 50 | *) 51 | return 1 52 | ;; 53 | esac 54 | echo "Types: deb" 55 | echo "URIs: http://${selected_uri_source}.ubuntu.com/${selected_uri_dir}/" 56 | if [[ ${sec} == "security" ]]; then 57 | echo "Suites: ${suite}-security" 58 | else 59 | echo "Suites: ${suite} ${suite}-updates ${suite}-backports" 60 | fi 61 | echo "Components: main universe restricted multiverse" 62 | echo "Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg" 63 | echo "Architectures-Remove: ${architectures}" 64 | echo "" 65 | } 66 | 67 | function generate_sources() { 68 | if [[ $(dpkg --print-architecture) == "arm64" ]]; then 69 | echo_repo_config "ports" "./devel" | sudo tee /etc/apt/sources.list.d/ubuntu.sources > /dev/null 70 | echo_repo_config "ports" "./devel" "security" | sudo tee -a /etc/apt/sources.list.d/ubuntu.sources > /dev/null 71 | else 72 | echo_repo_config "archive" "./devel" | sudo tee /etc/apt/sources.list.d/ubuntu.sources > /dev/null 73 | echo_repo_config "security" "./devel" "security" | sudo tee -a /etc/apt/sources.list.d/ubuntu.sources > /dev/null 74 | fi 75 | } 76 | 77 | function cleanup() { 78 | local sources_file sources_bak 79 | if [[ -f "/etc/apt/sources.list.d/ubuntu.sources-rhino.bak" ]]; then 80 | sources_file="/etc/apt/sources.list.d/ubuntu.sources" 81 | sources_bak="${sources_file}-rhino.bak" 82 | elif [[ -f "/etc/apt/sources.list-rhino.bak" ]]; then 83 | sources_file="/etc/apt/sources.list" 84 | sources_bak="${sources_file}-rhino.bak" 85 | else 86 | unset sources_file sources_bak 87 | fi 88 | source /etc/os-release && \ 89 | if [[ ${NAME} != "Rhino Linux" ]]; then 90 | if [[ -n "${sources_bak}" ]]; then 91 | echo "[${BCyan}~${NC}] ${BOLD}NOTE${NC}: Returning ${CYAN}${sources_file}${NC} backup..." 92 | sudo rm -f "${sources_file}" 93 | sudo mv "${sources_bak}" "${sources_file}" 94 | if [[ ${sources_file} == "/etc/apt/sources.list" ]]; then 95 | sudo rm -f /etc/apt/sources.list.d/ubuntu.sources 96 | fi 97 | fi 98 | if [[ -n ${OLD_VERSION_CODENAME} ]]; then 99 | if [[ ${VERSION_CODENAME} != "${OLD_VERSION_CODENAME}" ]]; then 100 | echo "[${BYellow}⚠${NC}] ${BOLD}CRITICAL${NC}: ${BCyan}lsb_release${NC} changed during install!" 101 | echo " [${BBlue}>${NC}] Updating ${CYAN}${sources_file}${NC} entries to ${BPurple}${VERSION_CODENAME}${NC} to avoid system breakage." 102 | if [[ ${VERSION_CODENAME} == "devel" ]]; then 103 | sudo sed -i -E "s|(\s)${OLD_VERSION_CODENAME}|\1./devel|g" ${sources_file} 104 | else 105 | sudo sed -i -E "s|(\s)${OLD_VERSION_CODENAME}|\1${VERSION_CODENAME}|g" ${sources_file} 106 | fi 107 | fi 108 | fi 109 | else 110 | if [[ -n "${sources_bak}" ]]; then 111 | echo "[${BYellow}⚠${NC}] ${BOLD}CRITICAL${NC}: script exited, but ${BRmPurple}Rhino Linux${NC} appears to be installed." 112 | echo " [${BBlue}>${NC}] Configuration likely incomplete. It is ${BOLD}highly${NC} recommended to re-run this script." 113 | echo " [${BBlue}>${NC}] You should select the same options. A fast track will be provided." 114 | echo " [${BBlue}>${NC}] Removing ${CYAN}${sources_file}${NC} backup to avoid system breakage." 115 | sudo rm -f "${sources_bak}" 116 | if ! grep devel /etc/apt/sources.list.d/ubuntu.sources >> /dev/null; then 117 | generate_sources 118 | fi 119 | fi 120 | fi 121 | } 122 | 123 | function test_compat() { 124 | local devarch 125 | if [[ -z $USER ]]; then 126 | export USER="$(whoami)" 127 | fi 128 | if [[ ${USER} == "root" ]]; then 129 | echo "[${BRed}!${NC}] ${BOLD}ERROR${NC}: ${BRmPurple}ub2r${NC} cannot be run as root!" 130 | exit 1 131 | fi 132 | devarch=${HOSTTYPE} 133 | if ! [[ ${devarch} == @(aarch64|arm64|x86_64|amd64) ]]; then 134 | echo "[${BRed}!${NC}] ${BOLD}ERROR${NC}: Rhino Linux only supports ${BCyan}amd64${NC} + ${BCyan}arm64${NC} as base architectures!" 135 | exit 1 136 | fi 137 | } 138 | 139 | function get_releaseinfo() { 140 | unset OLD_VERSION_CODENAME OLD_VERSION_ID OLD_NAME 141 | source /etc/os-release && \ 142 | OLD_VERSION_CODENAME="${VERSION_CODENAME}" 143 | OLD_VERSION_ID="${VERSION_ID}" 144 | OLD_NAME="${NAME}" 145 | if [[ ${ID} != "ubuntu" ]]; then 146 | echo "[${BRed}!${NC}] ${BOLD}ERROR${NC}: not an ${BUbOrange}Ubuntu${NC}-based system!" 147 | exit 1 148 | elif [[ ${OLD_NAME} == "Ubuntu" ]]; then 149 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: detected an ${BUbOrange}Ubuntu${NC} system." 150 | echo " [${BBlue}>${NC}] ${BOLD}VERSION ID${NC}: ${BYellow}${OLD_VERSION_ID}${NC}" 151 | echo " [${BBlue}>${NC}] ${BOLD}CODENAME${NC}: ${BPurple}${OLD_VERSION_CODENAME}${NC}" 152 | echo " [${BBlue}>${NC}] ${BOLD}USER${NC}: ${BCyan}${USER}${NC}" 153 | elif [[ ${OLD_NAME} == "Rhino Linux" ]]; then 154 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: detected a ${BRlPurple}Rhino Linux${NC} system." 155 | echo " [${BBlue}>${NC}] ${BOLD}VERSION ID${NC}: ${BYellow}${OLD_VERSION_ID}${NC}" 156 | echo " [${BBlue}>${NC}] ${BOLD}USER${NC}: ${BCyan}${USER}${NC}" 157 | else 158 | echo "[${BRed}!${NC}] ${BOLD}ERROR${NC}: not a ${BRlPurple}Rhino Linux${NC} compatible system!" 159 | exit 1 160 | fi 161 | } 162 | 163 | function ask() { 164 | local prompt default reply 165 | 166 | if [[ ${2-} == 'Y' ]]; then 167 | prompt="${BGreen}Y${NC}/${BRed}n${NC}" 168 | default='Y' 169 | elif [[ ${2-} == 'N' ]]; then 170 | prompt="${BGreen}y${NC}/${BRed}N${NC}" 171 | default='N' 172 | else 173 | prompt="${BGreen}y${NC}/${BRed}n${NC}" 174 | fi 175 | 176 | # Ask the question (not using "read -p" as it uses stderr not stdout) 177 | echo -ne "$1 [$prompt] " 178 | 179 | if [[ ${DISABLE_PROMPTS:-z} == "z" ]]; then 180 | export DISABLE_PROMPTS="no" 181 | fi 182 | 183 | if [[ $DISABLE_PROMPTS == "no" ]]; then 184 | read -r reply <&0 185 | # Detect if script is running non-interactively 186 | # Which implies that the input is being piped into the script 187 | if [[ $NON_INTERACTIVE ]]; then 188 | if [[ -z $reply ]]; then 189 | echo -n "$default" 190 | fi 191 | echo "$reply" 192 | fi 193 | else 194 | echo "$default" 195 | reply=$default 196 | fi 197 | 198 | # Default? 199 | if [[ -z $reply ]]; then 200 | reply=$default 201 | fi 202 | 203 | while :; do 204 | # Check if the reply is valid 205 | case "$reply" in 206 | Y* | y*) 207 | export answer=1 208 | return 0 #return code for backwards compatibility 209 | break 210 | ;; 211 | N* | n*) 212 | export answer=0 213 | return 1 #return code 214 | break 215 | ;; 216 | *) 217 | echo -ne "$1 [$prompt] " 218 | read -r reply < /dev/tty 219 | ;; 220 | esac 221 | done 222 | } 223 | 224 | function update_sources() { 225 | if ((${OLD_VERSION_ID%%.*} >= 24)) && [[ -f /etc/apt/sources.list.d/ubuntu.sources ]]; then 226 | echo "[${BYellow}*${NC}] ${BOLD}WARNING${NC}: Updating ${CYAN}/etc/apt/sources.list.d/ubuntu.sources${NC} entries to ${BPurple}./devel${NC}." 227 | echo " [${BBlue}>${NC}] If you have any PPAs, they may break!" 228 | echo " [${BBlue}>${NC}] Other sources contained in this file will be wiped." 229 | echo " [${BBlue}>${NC}] A backup will be created while this script runs, and it will be restored if cancelled." 230 | else 231 | echo "[${BYellow}*${NC}] ${BOLD}WARNING${NC}: Updating ${CYAN}/etc/apt/sources.list${NC} entries to ${BPurple}./devel${NC}." 232 | echo " [${BBlue}>${NC}] If you have any PPAs, they may break!" 233 | echo " [${BBlue}>${NC}] Other sources contained in this file will be wiped." 234 | echo " [${BBlue}>${NC}] A backup will be created while this script runs, and it will be restored if cancelled." 235 | echo " [${BBlue}>${NC}] A new deb-822 source list will be created at ${CYAN}/etc/apt/sources.list.d/ubuntu.sources${NC}." 236 | fi 237 | ask "[${BYellow}*${NC}] Continue?" N 238 | if ((answer == 0)); then 239 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: No changes made. Exiting..." 240 | exit 0 241 | else 242 | if ((${OLD_VERSION_ID%%.*} >= 24)) && [[ -f /etc/apt/sources.list.d/ubuntu.sources ]]; then 243 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: Creating backup of ${CYAN}/etc/apt/sources.list.d/ubuntu.sources${NC}..." 244 | sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources-rhino.bak 245 | sudo sed -i -E "s|(\s)${OLD_VERSION_CODENAME}|\1./devel|g" /etc/apt/sources.list.d/ubuntu.sources 246 | else 247 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: Creating backup of ${CYAN}/etc/apt/sources.list${NC}..." 248 | sudo mv /etc/apt/sources.list /etc/apt/sources.list-rhino.bak 249 | generate_sources 250 | fi 251 | fi 252 | echo "" 253 | } 254 | 255 | function install_pacstall() { 256 | if ! [[ -f "/usr/bin/pacstall" ]]; then 257 | echo "[${BCyan}~${NC}] ${BOLD}NOTE${NC}: Installing Pacstall..." 258 | echo -e "Y\nN" | sudo bash -c "$(curl -fsSL https://pacstall.dev/q/install || wget -q https://pacstall.dev/q/install -O -)" 259 | fi 260 | } 261 | 262 | function unicorn_flavor() { 263 | sudo update-alternatives --install /usr/share/icons/default/index.theme x-cursor-theme /usr/share/icons/Quintom_Snow/cursor.theme 55 264 | sudo update-alternatives --install /usr/share/icons/default/index.theme x-cursor-theme /usr/share/icons/Quintom_Ink/cursor.theme 55 265 | sudo update-alternatives --install /usr/share/plymouth/themes/default.plymouth default.plymouth /usr/share/plymouth/themes/rhino-spinner/rhino-spinner.plymouth 100 266 | sudo update-alternatives --set default.plymouth /usr/share/plymouth/themes/rhino-spinner/rhino-spinner.plymouth 267 | sudo update-alternatives --set x-cursor-theme /usr/share/icons/Quintom_Ink/cursor.theme 268 | if ! grep kvantum /etc/environment >> /dev/null; then 269 | echo "export QT_STYLE_OVERRIDE=kvantum" | sudo tee -a /etc/environment > /dev/null 270 | fi 271 | if ! [[ -f /etc/lightdm/rhino-blur.png ]]; then 272 | sudo rm -f /etc/lightdm/lightdm-gtk-greeter.conf 273 | (cd /etc/lightdm/ && \ 274 | sudo wget -q https://raw.githubusercontent.com/rhino-linux/lightdm/main/lightdm-gtk-greeter.conf && \ 275 | sudo wget -q https://github.com/rhino-linux/lightdm/raw/main/rhino-blur.png) 276 | fi 277 | sudo mkdir -p /home/$USER/.config/Kvantum 278 | echo "theme=KvRhinoDark" | sudo tee /home/$USER/.config/Kvantum/kvantum.kvconfig > /dev/null 279 | sudo mkdir -p /home/$USER/.config/xfce4 280 | sudo mkdir -p /home/$USER/.config/Kvantum 281 | sudo cp -r /etc/skel/.config/xfce4/* /home/$USER/.config/xfce4 282 | sudo cp -r /etc/skel/.config/Kvantum/* /home/$USER/.config/Kvantum 283 | if ! [[ -f "/home/$USER/.config/xfce4/desktop/icons.screen.latest.rc" ]]; then 284 | sudo ln -s "/home/$USER/.config/xfce4/desktop/icons.screen0-1904x990.rc" "/home/$USER/.config/xfce4/desktop/icons.screen.latest.rc" 285 | fi 286 | sudo chmod -R 777 /home/$USER/.config/xfce4 287 | sudo chown $USER -cR /home/$USER/.config > /dev/null 288 | } 289 | 290 | function is_apt_package_installed() { 291 | if [[ $(dpkg-query -W --showformat='${db:Status-Status}' "${1}" 2> /dev/null) == "installed" ]]; then 292 | return 0 293 | else 294 | return 1 295 | fi 296 | } 297 | 298 | function select_core() { 299 | echo "[${BCyan}~${NC}] ${BOLD}NOTE${NC}: Rhino Linux has three versions of our app suite. Which would you like to install?" 300 | echo " [${BBlue}>${NC}] ${BOLD}1)${NC} ${BPurple}rhino-server-core${NC}: TUI tool suite w/ basic development tools" 301 | echo " [${BBlue}>${NC}] ${BOLD}2)${NC} ${BPurple}rhino-ubxi-core${NC}: TUI+GUI app suite w/ GTK applications" 302 | echo " [${BBlue}>${NC}] ${BOLD}3)${NC} ${BPurple}rhino-core${NC}: Full suite w/ Unicorn Desktop Environment" 303 | unset packages core_package 304 | if ! is_apt_package_installed "nala"; then 305 | packages+=("nala-deb") 306 | fi 307 | while true; do 308 | read -p "[${BYellow}*${NC}] Enter your choice (${BGreen}1${NC}/${BGreen}2${NC}/${BGreen}3${NC}): " choice 309 | case $choice in 310 | 1) 311 | core_package="rhino-server-core" 312 | packages+=("${core_package}") 313 | break 314 | ;; 315 | 2) 316 | core_package="rhino-ubxi-core" 317 | packages+=("celeste-bin" "timeshift" "${core_package}") 318 | break 319 | ;; 320 | 3) 321 | core_package="rhino-core" 322 | packages+=("celeste-bin" "timeshift" "quintom-cursor-theme-git" "${core_package}" "rhino-setup-bin") 323 | break 324 | ;; 325 | *) ;; 326 | esac 327 | done 328 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: Selected to install ${BPurple}${core_package}${NC}." 329 | } 330 | 331 | function select_kernel() { 332 | echo "[${BCyan}~${NC}] ${BOLD}NOTE${NC}: Rhino Linux ships two versions of the Ubuntu mainline kernel:" 333 | echo " [${BBlue}>${NC}] ${BOLD}1)${NC} ${BPurple}linux-kernel${NC}: tracks the kernel ${YELLOW}mainline${NC} branch, with versions ${CYAN}X${NC}.${CYAN}X${NC}.${CYAN}0${NC}{${CYAN}-rcX${NC}}" 334 | echo " [${BBlue}>${NC}] ${BOLD}2)${NC} ${BPurple}linux-kernel-stable${NC}: tracks the kernel ${YELLOW}stable${NC} branch, with versions ${CYAN}X${NC}.(${CYAN}X-1${NC}).${CYAN}X${NC}" 335 | echo " [${BBlue}>${NC}] Would you like to install either of them? You can also say ${BRed}N${NC}/${BRed}n${NC} to remain on your current kernel." 336 | unset kern_package 337 | while true; do 338 | read -p "[${BYellow}*${NC}] Enter your choice (${BGreen}1${NC}/${BGreen}2${NC}/${BRed}N${NC}): " choice 339 | case $choice in 340 | 1) 341 | kern_package="linux-kernel" 342 | break 343 | ;; 344 | 2) 345 | kern_package="linux-kernel-stable" 346 | break 347 | ;; 348 | N | n) 349 | kern_package="none" 350 | break 351 | ;; 352 | *) ;; 353 | esac 354 | done 355 | if [[ ${kern_package} != "none" ]]; then 356 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: Selected to install ${BPurple}${kern_package}${NC}." 357 | else 358 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: Will not install any new kernels." 359 | fi 360 | echo "" 361 | } 362 | 363 | function is_package_installed() { 364 | local input="${1}" 365 | while read -r line; do 366 | if [[ ${line} == "${input}" ]]; then 367 | return 0 368 | fi 369 | done < <(pacstall -L) 370 | return 1 371 | } 372 | 373 | function install_packages() { 374 | local pkg 375 | install_pacstall || exit 1 376 | echo "[${BCyan}~${NC}] ${BOLD}NOTE${NC}: Upgrading packages, this may take a while..." 377 | sudo apt-get update --allow-releaseinfo-change && sudo DEBIAN_FRONTEND=noninteractive apt-get -o "Dpkg::Options::=--force-confold" dist-upgrade -y --allow-remove-essential --allow-change-held-packages || exit 1 378 | if [[ ${kern_package} != "none" ]]; then 379 | echo "[${BCyan}~${NC}] ${BOLD}NOTE${NC}: Installing ${BPurple}${kern_package}${NC}..." 380 | pacstall -PI ${kern_package} || exit 1 381 | else 382 | echo "[${BCyan}~${NC}] ${BOLD}NOTE${NC}: Not installing any kernels." 383 | fi 384 | echo "[${BCyan}~${NC}] ${BOLD}NOTE${NC}: Installing ${BPurple}${core_package}${NC} suite..." 385 | for pkg in "${packages[@]}"; do 386 | if [[ ${pkg} == "${core_package}" ]]; then 387 | pacstall -PI ${pkg} || exit 1 388 | if [[ ${pkg} == "rhino-core" ]]; then 389 | sudo apt install lightdm-gtk-greeter -yq || exit 1 390 | unicorn_flavor || exit 1 391 | fi 392 | elif ! is_package_installed "${pkg}"; then 393 | pacstall -PI ${pkg} || exit 1 394 | else 395 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: ${BPurple}${pkg}${NC} is already installed." 396 | fi 397 | done 398 | } 399 | 400 | test_compat 401 | echo -e "${RDPURPLE}┌─────────────────────────────┐\n│${NC} Welcome to ${BRlPurple}ub2r${NC} ${RDPURPLE}│\n│${NC} A tool to convert ${RDPURPLE}│\n│${NC} ${BUbOrange}Ubuntu${NC} to ${BRmPurple}Rhino Linux${NC} ${RDPURPLE}│\n└─────────────────────────────┘${NC}" 402 | get_releaseinfo 403 | echo "[${BCyan}~${NC}] ${BOLD}NOTE${NC}: You may be asked to enter your password more than once." 404 | sleep 1 405 | echo "" 406 | 407 | if [[ ${OLD_NAME} != "Rhino Linux" ]]; then 408 | trap "cleanup && exit 1" EXIT 409 | trap "cleanup && exit 1" INT 410 | update_sources || { 411 | cleanup 412 | exit 1 413 | } 414 | if grep "Raspberry Pi" /proc/cpuinfo >> /dev/null; then 415 | kern_package="none" 416 | else 417 | select_kernel || { 418 | cleanup 419 | exit 1 420 | } 421 | fi 422 | select_core || { 423 | cleanup 424 | exit 1 425 | } 426 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: All set! We'll do the rest. Starting in 3 seconds..." 427 | sleep 3 428 | echo "" 429 | if install_packages; then 430 | if ((${OLD_VERSION_ID%%.*} >= 24)) && [[ -f /etc/apt/sources.list.d/ubuntu.sources-rhino.bak ]]; then 431 | echo "[${BCyan}~${NC}] ${BOLD}NOTE${NC}: Removing ${CYAN}/etc/apt/sources.list.d/ubuntu.sources${NC} backup..." 432 | sudo rm -f /etc/apt/sources.list.d/ubuntu.sources-rhino.bak 433 | else 434 | echo "[${BCyan}~${NC}] ${BOLD}NOTE${NC}: Removing ${CYAN}/etc/apt/sources.list${NC} backup..." 435 | sudo rm -f /etc/apt/sources.list-rhino.bak 436 | fi 437 | neofetch --ascii_distro rhino_small 438 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: ${BGreen}Finished${NC}! You can now use ${BRmPurple}rhino-pkg${NC}/${BRlPurple}rpk${NC} to manage your packages." 439 | echo " [${BBlue}>${NC}] Be sure to reboot when you are done checking it out!" 440 | else 441 | cleanup 442 | exit 1 443 | fi 444 | else 445 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: Rhino Linux appears to already be installed." 446 | ask "[${BYellow}*${NC}] Do you want to change kernels and/or suites?" N 447 | if ((answer == 0)); then 448 | echo "[${BCyan}~${NC}] No changes made. Exiting..." 449 | exit 0 450 | else 451 | if grep "Raspberry Pi" /proc/cpuinfo >> /dev/null; then 452 | kern_package="none" 453 | else 454 | select_kernel || exit 1 455 | fi 456 | select_core || exit 1 457 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: All set! Starting in 3 seconds..." 458 | sleep 3 459 | echo "" 460 | if install_packages; then 461 | neofetch --ascii_distro rhino_small 462 | echo "[${BGreen}+${NC}] ${BOLD}INFO${NC}: ${BGreen}Finished${NC}! Be sure to reboot if you installed any new kernels." 463 | else 464 | exit 1 465 | fi 466 | fi 467 | fi 468 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | --------------------------------------------------------------------------------