diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index f10600cf6..d139dbd2f 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -70,7 +70,7 @@ runs: - name: Setup Python uses: actions/setup-python@v4 with: - python-version: '3.10' + python-version: '3.11' - name: Cache Python environment uses: actions/cache@v3 id: cache-python diff --git a/.github/actions/sync-repository/action.yml b/.github/actions/sync-repository/action.yml index 7a213bfe0..01b7aa50a 100644 --- a/.github/actions/sync-repository/action.yml +++ b/.github/actions/sync-repository/action.yml @@ -28,7 +28,7 @@ runs: echo '${{ inputs.ssh-key }}' > private/id_rsa echo '${{ inputs.ssh-known-hosts }}' > private/known_hosts chmod 600 private/* - rsync --archive --verbose --compress --delete \ + rsync --archive --verbose --compress --delete --hard-links \ -e "ssh -p ${{ inputs.ssh-port }} -i private/id_rsa -o UserKnownHostsFile=private/known_hosts" \ '${{ inputs.local-path }}' \ '${{ inputs.remote-path }}' diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 7968bff0e..a0dbca99c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -30,3 +30,15 @@ jobs: with: name: repo path: build/repo + - name: Build packages for experimental + if: ${{ contains(github.event.pull_request.labels.*.name, 'experimental') }} + run: make repo FLAGS='--remote-repo https://toltec-dev.org/${{ github.base_ref }}' + - name: Sync packages with the remote repository + if: ${{ contains(github.event.pull_request.labels.*.name, 'experimental') }} + uses: ./.github/actions/sync-repository + with: + local-path: build/repo/ + ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} + ssh-known-hosts: ${{ secrets.SSH_KNOWN_HOSTS }} + ssh-port: ${{ secrets.SSH_PORT }} + remote-path: ${{ secrets.REMOTE_SSH }}:/srv/toltec/experimental diff --git a/docs/package.md b/docs/package.md index 72a9bdca8..bdaf7807a 100644 --- a/docs/package.md +++ b/docs/package.md @@ -38,11 +38,17 @@ You can also declare custom variables to reduce repetition but make sure to pref The list of devices that are compatible with this package. The following values are accepted: -Name | Meaning ---------|------------------------------------------------------------------------- -`rmall` | Packages which work on all reMarkable devices without modification. -`rm1` | Packages requiring reMarkable 1-specific resources or compilation flags. -`rm2` | Packages requiring reMarkable 2-specific resources or compilation flags. +Name | Meaning +------------|------------------------------------------------------------------------- +`rmall` | Packages which work on all reMarkable devices without modification. +`rm1` | Packages requiring reMarkable 1-specific resources or compilation flags. +`rm2` | Packages requiring reMarkable 2-specific resources or compilation flags. +`rmallos2` | Packages which work on all reMarkable devices without modification, but only on the 2.x series of operating system. +`rm1os2` | Packages requiring reMarkable 1-specific resources or compilation flags, but only on the 2.x series of operating system. +`rm2os2` | Packages requiring reMarkable 2-specific resources or compilation flags, but only on the 2.x series of operating system. +`rmallos3` | Packages which work on all reMarkable devices without modification, but only on the 3.x series of operating system. +`rm1os3` | Packages requiring reMarkable 1-specific resources or compilation flags, but only on the 3.x series of operating system. +`rm2os3` | Packages requiring reMarkable 2-specific resources or compilation flags, but only on the 3.x series of operating system. For example, use `archs=(rm1)` for a package that only works on reMarkable 1, or `archs=(rm1 rm2)` for a package that works both on reMarkable 1 and reMarkable 2 but needs different dependencies or compilation flags for each of those. diff --git a/package/Compatibility b/package/Compatibility new file mode 100644 index 000000000..cf3ac4c40 --- /dev/null +++ b/package/Compatibility @@ -0,0 +1,70 @@ +rm1=2.6.1.71 +rm1=2.6.2.75 +rm1=2.7.0.9 +rm1=2.7.0.30 +rm1=2.7.0.36 +rm1=2.7.0.44 +rm1=2.7.0.51 +rm1=2.8.0.81 +rm1=2.8.0.86 +rm1=2.8.0.98 +rm1=2.9.0.153 +rm1=2.9.0.204 +rm1=2.9.0.210 +rm1=2.9.1.217 +rm1=2.9.1.236 +rm1=2.10.2.356 +rm1=2.10.3.379 +rm1=2.11.0.442 +rm1=2.12.1.527 +rm1=2.12.2.573 +rm1=2.12.3.606 +rm1=2.13.0.758 +rm1=2.14.0.861 +rm1=2.14.1.866 +rm1=2.14.3.958 +rm1=2.14.3.977 +rm1=2.14.3.1005 +rm1=2.14.3.1047 +rm1=2.15.0.1067 +rm1=2.15.1.1189 +rm1=3.0.4.1305 +rm1=3.2.2.1581 +rm1=3.2.3.1595 +rm1=3.3.2.1666 + +rm2=2.6.1.71 +rm2=2.6.2.75 +rm2=2.7.0.9 +rm2=2.7.0.30 +rm2=2.7.0.36 +rm2=2.7.0.44 +rm2=2.7.0.51 +rm2=2.7.1.53 +rm2=2.8.0.81 +rm2=2.8.0.86 +rm2=2.8.0.98 +rm2=2.9.0.153 +rm2=2.9.0.204 +rm2=2.9.0.210 +rm2=2.9.1.217 +rm2=2.9.1.236 +rm2=2.10.2.356 +rm2=2.10.3.379 +rm2=2.11.0.442 +rm2=2.12.1.527 +rm2=2.12.2.573 +rm2=2.12.3.606 +rm2=2.13.0.758 +rm2=2.14.0.861 +rm2=2.14.1.866 +rm2=2.14.3.958 +rm2=2.14.3.977 +rm2=2.14.3.1005 +rm2=2.14.3.1047 +rm2=2.15.0.1067 +rm2=2.15.1.1189 +rm2=3.0.4.1305 +rm2=3.2.2.1581 +rm2=3.2.3.1595 +rm2=3.3.2.1666 diff --git a/package/ddvk-hacks/package b/package/ddvk-hacks/package index 70423edd9..edf8b1f12 100644 --- a/package/ddvk-hacks/package +++ b/package/ddvk-hacks/package @@ -2,11 +2,11 @@ # Copyright (c) 2021 The Toltec Contributors # SPDX-License-Identifier: MIT -archs=(rm1 rm2) +archs=(rm1os2 rm2os2) pkgnames=(ddvk-hacks) pkgdesc="Enhance Xochitl with additional features" url=https://github.com/ddvk/remarkable-hacks -pkgver=39.01-2 +pkgver=39.01-4 timestamp=2022-11-09T18:31:51Z section="readers" maintainer="Mattéo Delabre " @@ -20,55 +20,58 @@ sha256sums=(d3b1413bb9219804581afab598e7f5308233e7467d64e8084e67aae7346beaba) _patches_dir="/opt/share/ddvk-hacks" _xochitl_path="/usr/bin/xochitl" _work_dir="/home/root/.local/share/ddvk-hacks" +_info_path="$_work_dir/xochitl.info" _backup_path="$_work_dir/xochitl.backup" _old_backup_path="$_backup_path.old" _patched_path="$_work_dir/xochitl.patched" package() { - if [[ $arch = rm1 ]]; then - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/26171_rm1/patch_19.1.02 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/26275_rm1/patch_20.1.03 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/27051_rm1/patch_21.1.04 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/28098_rm1/patch_23.1.02 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/291236_rm1/patch_24.1.02 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2100324_rm1/patch_25.1.03 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2102356_rm1/patch_27.1.03 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2103379_rm1/patch_28.1.02 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2110442_rm1/patch_29.1.02 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2121527_rm1/patch_30.1.08 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2122573_rm1/patch_31.1.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2123606_rm1/patch_32.1.03 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2140861_rm1/patch_34.1.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2141866_rm1/patch_35.1.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2143977_rm1/patch_36.1.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/21431047_rm1/patch_37.1.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/21501067_rm1/patch_38.1.03 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/21511189_rm1/patch_39.1.01 - elif [[ $arch = rm2 ]]; then - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/26171_rm2/patch_19.2.02 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/26275_rm2/patch_20.2.03 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/27051_rm2/patch_21.2.05 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/27153_rm2/patch_22.2.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/28098_rm2/patch_23.2.02 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/291217_rm2/patch_24.2.04 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2100324_rm2/patch_25.2.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2101332_rm2/patch_26.2.02 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2102356_rm2/patch_27.2.05 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2103379_rm2/patch_28.2.02 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2110442_rm2/patch_29.2.02 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2121527_rm2/patch_30.2.07 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2122573_rm2/patch_31.2.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2123606_rm2/patch_32.2.02 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2130758_rm2/patch_33.2.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2140861_rm2/patch_34.2.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2141866_rm2/patch_35.2.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/2143977_rm2/patch_36.2.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/21431047_rm2/patch_37.2.01 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/21501067_rm2/patch_38.2.03 - install -D -m 644 -t "$pkgdir$_patches_dir" "$srcdir"/patches/21511189_rm2/patch_39.2.01 + mkdir -p "$pkgdir"/opt/share/toltec/reenable.d + touch "$pkgdir"/opt/share/toltec/reenable.d/"$pkgname" + if [[ $arch = rm1os2 ]]; then + patches_dir="${pkgdir}${_patches_dir}" + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/26171_rm1/patch_19.1.02 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/26275_rm1/patch_20.1.03 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/27051_rm1/patch_21.1.04 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/28098_rm1/patch_23.1.02 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/291236_rm1/patch_24.1.02 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2100324_rm1/patch_25.1.03 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2102356_rm1/patch_27.1.03 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2103379_rm1/patch_28.1.02 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2110442_rm1/patch_29.1.02 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2121527_rm1/patch_30.1.08 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2122573_rm1/patch_31.1.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2123606_rm1/patch_32.1.03 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2140861_rm1/patch_34.1.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2141866_rm1/patch_35.1.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2143977_rm1/patch_36.1.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/21431047_rm1/patch_37.1.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/21501067_rm1/patch_38.1.03 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/21511189_rm1/patch_39.1.01 + elif [[ $arch = rm2os2 ]]; then + patches_dir="${pkgdir}${_patches_dir}" + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/26171_rm2/patch_19.2.02 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/26275_rm2/patch_20.2.03 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/27051_rm2/patch_21.2.05 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/27153_rm2/patch_22.2.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/28098_rm2/patch_23.2.02 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/291217_rm2/patch_24.2.04 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2100324_rm2/patch_25.2.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2101332_rm2/patch_26.2.02 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2102356_rm2/patch_27.2.05 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2103379_rm2/patch_28.2.02 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2110442_rm2/patch_29.2.02 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2121527_rm2/patch_30.2.07 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2122573_rm2/patch_31.2.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2123606_rm2/patch_32.2.02 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2130758_rm2/patch_33.2.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2140861_rm2/patch_34.2.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2141866_rm2/patch_35.2.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/2143977_rm2/patch_36.2.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/21431047_rm2/patch_37.2.01 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/21501067_rm2/patch_38.2.03 + install -D -m 644 -t "$patches_dir" "$srcdir"/patches/21511189_rm2/patch_39.2.01 fi - touch "$srcdir"/emptyfile - install -D -m 666 -t "$pkgdir"/usr/share/toltec/reenable.d/ddvk-hacks "$srcdir"/emptyfile } configure() { @@ -78,7 +81,7 @@ configure() { local device local original_hash local xochitl_version - if [[ $arch = rm1 ]]; then + if [[ $arch = rm1os2 ]]; then device="reMarkable 1" case "$build_date" in "20221026103859") @@ -179,7 +182,7 @@ configure() { exit 1 ;; esac - elif [[ $arch = rm2 ]]; then + elif [[ $arch = rm2os2 ]]; then device="reMarkable 2" case "$build_date" in "20221026104022") @@ -328,11 +331,25 @@ configure() { cp "$_patched_path" "$_xochitl_path" rm -rf /home/root/.cache/remarkable/xochitl/qmlcache/* + # shellcheck source=../toltec-bootstrap/toltecctl + source /home/root/.local/bin/toltecctl + get-release-version > "$_info_path" + echo "Please restart Xochitl to use the patches" echo } _restore() { + # shellcheck source=../toltec-bootstrap/toltecctl + source /home/root/.local/bin/toltecctl + + if ! [ -f "$_info_path" ] \ + || [[ "$(get-release-version)" != "$(cat "$_info_path")" ]] \ + || compare-versions "$(get-release-version)" "3.0"; then + echo "Skipping restore, as you are on a newer OS version" + return + fi + echo echo "Restoring the original Xochitl binary" @@ -342,6 +359,7 @@ _restore() { else cp "$_backup_path" "$_xochitl_path" rm -rf /home/root/.cache/remarkable/xochitl/qmlcache/* + rm "$_info_path" fi echo diff --git a/package/display/package b/package/display/package index affb56eee..8f3bd3029 100644 --- a/package/display/package +++ b/package/display/package @@ -8,7 +8,7 @@ timestamp=2023-08-27T02:39:10Z maintainer="raisjn " license=MIT url="https://github.com/ddvk/remarkable2-framebuffer" -pkgver=1:0.0.32-2 +pkgver=1:0.0.33-1 _release="${pkgver%-*}" _release="v${_release#*:}" _libver=1.0.1 @@ -23,7 +23,7 @@ source=( rm2fb-preload.env ) sha256sums=( - 603eef1688a8c3adb1df23f4f00fe12b80938fe99801b515cd74f84c8cede5b1 + dd57f1ba31f08a28d801989e9a705bd93cc637cd8f4dffa160412119e69329ff SKIP SKIP SKIP diff --git a/package/draft/launcherctl-draft b/package/draft/launcherctl-draft new file mode 100644 index 000000000..a3c0b9db2 --- /dev/null +++ b/package/draft/launcherctl-draft @@ -0,0 +1,93 @@ +#!/bin/bash +set -e +draft_pid() { + systemctl show --no-pager --property MainPID draft.service | sed 's|MainPID=||' +} +kill_pid() { + pid="$1" + if [[ "$(awk '{print $3}' "/proc/${pid}/stat")" == "T" ]]; then + kill -CONT "$pid" + fi + kill -TERM "$pid" + # Wait 5s for process to exit + start="$(date +'%s')" + while kill -0 "$pid" 2> /dev/null; do + sleep 0.5 + if [ "$(date +'%s')" -gt $((start + 5)) ]; then + break + fi + done + if kill -0 "$pid" 2> /dev/null; then + # If process is still running, force kill it + kill -KILL "$pid" + fi +} +case "$1" in + is-active) + systemctl is-active --quiet draft.service + ;; + is-enabled) + systemctl is-enabled --quiet draft.service + ;; + logs) + if [ $# -eq 2 ] && [[ "$2" == "-f" ]] || [[ "$2" == "--follow" ]]; then + journalctl --follow --all --unit draft.service + else + journalctl --no-pager --all --unit draft.service + fi + ;; + start) + systemctl start draft.service + ;; + stop) + systemctl stop draft.service + ;; + enable) + systemctl enable draft.service + ;; + disable) + systemctl disable draft.service + ;; + apps) + find {/opt,}/etc/draft -maxdepth 1 -type f | while read -r file; do + grep 'name=' "$file" | sed 's|^name=||' + done + ;; + close) + find {/opt,}/etc/draft -maxdepth 1 -type f | while read -r file; do + if [[ "$(grep 'name=' "$file" | sed 's|^name=||')" == "$2" ]]; then + term="$(grep 'term=' "$file" | sed 's|^term=||')" + if [ -z "$term" ]; then + echo "No term= configuration specified for ${2}" + exit 1 + fi + $term + call="$(grep 'call=' "$file" | sed 's|^call=||')" + name="$(grep 'name=' "$file" | sed 's|^name=||')" + /opt/libexec/ps-procps-ng --ppid "$(draft_pid)" -o pid | tail -n +2 | while read -r pid; do + if [[ "$(tr -d '\0' < "/proc/${pid}/cmdline")" == "$call" ]]; then + kill_pid "$pid" + break + fi + done + fi + done + ;; + running) + pid=$(draft_pid) + find {/opt,}/etc/draft -maxdepth 1 -type f | while read -r file; do + call="$(grep 'call=' "$file" | sed 's|^call=||')" + name="$(grep 'name=' "$file" | sed 's|^name=||')" + /opt/libexec/ps-procps-ng --ppid "$(draft_pid)" -o pid | tail -n +2 | while read -r pid; do + if [[ "$(tr -d '\0' < "/proc/${pid}/cmdline")" == "$call" ]]; then + echo "$name" + break + fi + done + done + ;; + *) + echo "Draft does not support this method" + exit 1 + ;; +esac diff --git a/package/draft/package b/package/draft/package index aac94f8e6..81610e407 100644 --- a/package/draft/package +++ b/package/draft/package @@ -5,22 +5,24 @@ pkgnames=(draft) pkgdesc="Launcher which wraps around the standard interface" url=https://github.com/dixonary/draft-reMarkable -pkgver=0.2.0-22 +pkgver=0.2.0-25 timestamp=2020-07-20T10:23Z section="launchers" maintainer="Mattéo Delabre " license=Apache-2.0 -installdepends=(xochitl display) +installdepends=(xochitl display procps-ng-ps) flags=(patch_rm2fb) image=qt:v2.1 source=( https://github.com/dixonary/draft-reMarkable/archive/5bd660a2fd07eba166c6110d2b48cfc58ee67e58.zip draft.service + launcherctl-draft ) sha256sums=( c41d7a4fd537c54d787018fd764421dbf7dd64306ca800875283e05eef99173e SKIP + SKIP ) build() { @@ -46,21 +48,25 @@ package() { mv "$pkgdir"/opt/etc/draft/{99-,}shutdown install -D -m 644 -t "$pkgdir"/lib/systemd/system "$srcdir"/draft.service + install -D -T -m 755 "$srcdir"/launcherctl-draft "$pkgdir"/opt/share/launcherctl/"$pkgname" } configure() { systemctl daemon-reload - if ! is-enabled "$pkgname.service"; then + if ! launcherctl is-current-launcher "$pkgname"; then echo "" echo "Run the following command(s) to use $pkgname as your launcher" - how-to-enable "$pkgname.service" + echo "launcherctl switch-launcher --start $pkgname" echo "" fi } preremove() { - disable-unit "$pkgname.service" + # Just in case more than one launcher is active, do individual checks + if launcherctl is-active-launcher "$pkgname" || launcherctl is-enabled-launcher "$pkgname"; then + launcherctl switch-launcher --start xochitl + fi } postremove() { diff --git a/package/entware-rc/entware-rc@.service b/package/entware-rc/entware-rc@.service new file mode 100644 index 000000000..f76fb3466 --- /dev/null +++ b/package/entware-rc/entware-rc@.service @@ -0,0 +1,13 @@ +[Unit] +Description=Entware %I service +After=opt.mount + +[Service] +ExecStart=/opt/etc/init.d/%I start +ExecStop=/opt/etc/init.d/%I stop +Type=forking +GuessMainPID=true +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/package/entware-rc/package b/package/entware-rc/package new file mode 100644 index 000000000..40b8432f4 --- /dev/null +++ b/package/entware-rc/package @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Copyright (c) 2024 The Toltec Contributors +# SPDX-License-Identifier: MIT + +archs=(rmall) +pkgnames=(entware-rc) +pkgdesc="Manage entware installed services" +url=https://toltec-dev.org/ +pkgver=0.1-1 +timestamp=2024-05-22T22:59:03Z +section="utils" +maintainer="Eeems " +license=MIT +installdepends=() + +source=( + entware-rc@.service + rcctl +) +sha256sums=( + SKIP + SKIP +) + +package() { + install -D -m 666 -t "$pkgdir"/lib/systemd/system/ "$srcdir"/entware-rc@.service + install -D -m 755 -t "$pkgdir"/opt/bin/ "$srcdir"/rcctl +} + +configure() { + systemctl daemon-reload + echo "" + echo "You can use rcctl to manage services installed by entware" +} + +preremove() { + rcctl list | xargs -I {} systemctl disable --now entware-rc@{} +} diff --git a/package/entware-rc/rcctl b/package/entware-rc/rcctl new file mode 100755 index 000000000..899ae7862 --- /dev/null +++ b/package/entware-rc/rcctl @@ -0,0 +1,62 @@ +#!/bin/bash +help() { + echo "Usage: rcctl " + echo " commands:" + echo " help: Display this message and exit" + echo " start : Start a service" + echo " stop : Stop a service" + echo " restart : Restart a service" + echo " enable : Enable service startup on boot" + echo " disable : Disable service startup on boot" + echo " status []: View the current status of services" + echo " logs [-f|--follow] : View logs for a service" + echo " list: List available services" +} +if [[ $1 == "help" ]] || [[ $1 == "--help" ]]; then + help +elif [[ $1 == "start" ]] \ + || [[ $1 == "stop" ]] \ + || [[ $1 == "restart" ]] \ + || [[ $1 == "enable" ]] \ + || [[ $1 == "disable" ]]; then + if [ $# -ge 3 ]; then + echo "Too many arguments" + exit 1 + elif [ $# -lt 2 ]; then + echo "Too few arguments" + exit 1 + fi + systemctl "$1" "entware-rc@$2.service" +elif [[ $1 == "status" ]]; then + if [ $# -ge 3 ]; then + echo "Too many arguments" + exit 1 + elif [ $# -eq 1 ]; then + "$0" list | xargs -rn1 "$0" status + else + s="entware-rc@${2}.service" + echo "${2}" "$(systemctl is-active "${s}")" "$(systemctl is-enabled "${s}")" \ + | grep --color=always '\(disabled\|inactive\|$\)' + fi +elif [[ $1 == "logs" ]]; then + if [ $# -ge 4 ]; then + echo "Too many arguments" + exit 1 + elif [ $# -lt 2 ]; then + echo "Too few arguments" + exit 1 + elif [ $# -eq 3 ] && [[ "$2" != "-f" ]] && [[ "$2" != "--follow" ]]; then + echo "Invalid arguments" + exit 1 + fi + if [ $# -eq 3 ]; then + journalctl --no-pager -all --follow --unit "entware-rc@${3}.service" + else + journalctl --no-pager -all --unit "entware-rc@${2}.service" + fi +elif [[ $1 == "list" ]]; then + /opt/bin/find /opt/etc/init.d/ -perm '-u+x' -name 'S*' | xargs -rn1 basename +else + help + exit 1 +fi diff --git a/package/fuse/package b/package/fuse/package index 4c80b0bce..bb3c88a41 100755 --- a/package/fuse/package +++ b/package/fuse/package @@ -2,11 +2,11 @@ # Copyright (c) 2020 The Toltec Contributors # SPDX-License-Identifier: MIT -archs=(rm1 rm2) +archs=(rm1os2 rm2os2) pkgnames=(fuse) pkgdesc="FUSE (Filesystem in Userspace) Kernel Module" url=https://github.com/libfuse/libfuse -pkgver=1.0.0-4 +pkgver=1.0.0-5 timestamp=2021-04-06T22:16Z section=kernel maintainer="plan5 <30434574+plan5@users.noreply.github.com>" @@ -51,14 +51,14 @@ build() { } package() { - if [[ $arch = rm1 ]]; then + if [[ $arch = rm1os2 ]]; then mkdir -p "$pkgdir/lib/modules" cp -r "$srcdir/pkg"/* "$pkgdir/lib/modules" fi } configure() { - if [[ $arch = rm1 ]]; then + if [[ $arch = rm1os2 ]]; then # Regenerate /lib/modules/[ver]/modules.devname to request the # creation of /dev/fuse used for on-demand loading of fuse depmod -a @@ -72,7 +72,7 @@ configure() { } postremove() { - if [[ $arch = rm1 ]]; then + if [[ $arch = rm1os2 ]]; then echo 'Fuse (Kernel Module) has been removed.' echo 'The kernel module will remain loaded until you reboot, or you can attempt' echo 'to manually remove it by running "modprobe -r fuse".' @@ -81,7 +81,7 @@ postremove() { } postupgrade() { - if [[ $arch = rm1 ]]; then + if [[ $arch = rm1os2 ]]; then echo 'Fuse (Kernel Module) has been upgraded.' echo 'The old kernel module will remain loaded until you reboot, or you can' echo 'attempt to manually remove it by running "modprobe -r fuse".' diff --git a/package/gocryptfs/package b/package/gocryptfs/package index 2c7965ae1..c6b4dd8e9 100644 --- a/package/gocryptfs/package +++ b/package/gocryptfs/package @@ -2,11 +2,12 @@ # Copyright (c) 2020 The Toltec Contributors # SPDX-License-Identifier: MIT +archs=(rmallos2) pkgnames=(gocryptfs) pkgdesc="An encrypted overlay filesystem written in Go." url="https://nuetzlich.net/gocryptfs/" _srcver=2.0-beta2 -pkgver="$_srcver"-2 +pkgver="$_srcver"-3 timestamp=2021-03-22 section=utils maintainer="plan5 <30434574+plan5@users.noreply.github.com>" diff --git a/package/innernet/package b/package/innernet/package index 61f08ff16..db2510734 100644 --- a/package/innernet/package +++ b/package/innernet/package @@ -2,10 +2,11 @@ # Copyright (c) 2021 The Toltec Contributors # SPDX-License-Identifier: MIT +archs=(rmallos2) pkgnames=(innernet-client) pkgdesc="A private network system that uses WireGuard under the hood." url="https://github.com/tonarino/innernet" -pkgver=1.5.3-2 +pkgver=1.5.3-3 timestamp=2022-01-31T20:08:43Z section="utils" maintainer="plan5 <30434574+plan5@users.noreply.github.com>" diff --git a/package/kernelctl/package b/package/kernelctl/package index f4a4b36be..dcfcd5f7d 100644 --- a/package/kernelctl/package +++ b/package/kernelctl/package @@ -5,7 +5,7 @@ pkgnames=(kernelctl) pkgdesc="Manage aftermarket kernels" url=https://toltec-dev.org/ -pkgver=0.1-6 +pkgver=0.1-7 timestamp=2022-11-12T00:00Z section="utils" maintainer="Salvatore Stella " @@ -19,10 +19,10 @@ sha256sums=( ) package() { - touch "$srcdir"/emptyfile install -D -m 744 -t "$pkgdir"/opt/bin "$srcdir"/kernelctl install -d "$pkgdir"/opt/usr/share/kernelctl - install -D -m 666 -t "$pkgdir"/usr/share/toltec/reenable.d/kernelctl "$srcdir"/emptyfile + mkdir -p "$pkgdir"/opt/share/toltec/reenable.d + touch "$pkgdir"/opt/share/toltec/reenable.d/"$pkgname" } configure() { diff --git a/package/koreader/launcherctl-koreader b/package/koreader/launcherctl-koreader new file mode 100755 index 000000000..6e605d286 --- /dev/null +++ b/package/koreader/launcherctl-koreader @@ -0,0 +1,41 @@ +#!/bin/bash +set -e +case "$1" in + is-active) + systemctl is-active --quiet koreader.service + ;; + is-enabled) + systemctl is-enabled --quiet koreader.service + ;; + logs) + if [ $# -eq 2 ] && [[ "$2" == "-f" ]] || [[ "$2" == "--follow" ]]; then + journalctl --follow --all --unit koreader.service + else + journalctl --no-pager --all --unit koreader.service + fi + ;; + start | launch) + systemctl start koreader.service + ;; + stop | close) + systemctl stop koreader.service + ;; + enable) + systemctl enable koreader.service + ;; + disable) + systemctl disable koreader.service + ;; + apps) + echo "koreader" + ;; + running) + if "$0" is-active; then + echo "koreader" + fi + ;; + *) + echo "KOReader does not support this method" + exit 1 + ;; +esac diff --git a/package/koreader/package b/package/koreader/package index 9f91852d2..ff323c2e1 100644 --- a/package/koreader/package +++ b/package/koreader/package @@ -5,8 +5,8 @@ pkgnames=(koreader) pkgdesc="Ebook reader supporting PDF, DjVu, EPUB, FB2 and many more formats" url=https://github.com/koreader/koreader -pkgver=2024.01-1 -timestamp=2024-01-11T17:16:35Z +pkgver=2024.04-4 +timestamp=2024-04-29T19:56:05Z section="readers" maintainer="raisjn " license=AGPL-3.0-or-later @@ -19,9 +19,11 @@ source=( KOReader.oxide koreader-toltec.service koreader + launcherctl-koreader ) sha256sums=( - 2616c7f0c63d54810f4ec78477ecb5dac2443990c7d2c8188c577ad5d925cca1 + e6b3a5a2c8cde8ca0c469fe542d6e170502fcf39b9a55e4447a7acd02b4a12c0 + SKIP SKIP SKIP SKIP @@ -41,6 +43,7 @@ package() { install -D -m 644 "$srcdir"/koreader-toltec.service "$pkgdir"/lib/systemd/system/koreader.service install -D -m 644 -t "$pkgdir"/opt/etc/draft/icons/ "$srcdir"/resources/koreader.png install -D -m 755 -t "$pkgdir"/opt/bin/ "$srcdir"/koreader + install -D -T -m 755 "$srcdir"/launcherctl-koreader "$pkgdir"/opt/share/launcherctl/"$pkgname" } configure() { @@ -51,18 +54,19 @@ configure() { systemctl daemon-reload - if ! is-enabled "$pkgname.service"; then - cat << MSG - -Run the following command(s) to use $pkgname as your launcher -$(how-to-enable "$pkgname.service") - -MSG + if ! launcherctl is-current-launcher "$pkgname"; then + echo "" + echo "Run the following command(s) to use $pkgname as your launcher" + echo "launcherctl switch-launcher --start $pkgname" + echo "" fi } preremove() { - disable-unit "$pkgname.service" + # Just in case more than one launcher is active, do individual checks + if launcherctl is-active-launcher "$pkgname" || launcherctl is-enabled-launcher "$pkgname"; then + launcherctl switch-launcher --start xochitl + fi } postremove() { diff --git a/package/launcherctl/launcherctl b/package/launcherctl/launcherctl new file mode 100755 index 000000000..ff87e6a0f --- /dev/null +++ b/package/launcherctl/launcherctl @@ -0,0 +1,199 @@ +#!/bin/bash +set -e +help() { + echo "Usage: launcherctl " + echo " commands:" + echo " help: Display this message and exit" + echo " status: Current launcher status" + echo " logs [-f|--follow]: View current launcher logs" + echo " list-launchers: List installed launchers" + echo " switch-launcher [--start] : Switch which launcher is active" + echo " start-launcher: Start the current launcher" + echo " stop-launcher: Stop the current launcher" + echo " list-apps: List all application for current launcher" + echo " list-running-apps: List all application for current launcher" + echo " start-app : Start an application with the current launcher" + echo " stop-app : Stop an application with the current launcher" + echo " pause-app : Pause an application with the current launcher" + echo " resume-app : Resume an application with the current launcher" + echo " is-current-launcher : Check if the launcher is the current launcher" + echo " is-enabled-launcher : Check if the launcher is enabled" + echo " is-active-launcher : Check if the launcher is active" +} +data_dir="/opt/share/launcherctl" +launchers() { + /opt/bin/find "$data_dir" -type f -perm '-u+x' | xargs -rn1 basename +} +active_launchers() { + launchers | while read -r launcher; do + if query "$launcher" is-active; then + echo "$launcher" + fi + done +} +enabled_launchers() { + launchers | while read -r launcher; do + if query "$launcher" is-enabled; then + echo "$launcher" + fi + done +} +query() { + launcher="$1" + shift + "${data_dir}/${launcher}" "$@" +} +check_enabled_launchers() { + if [ "$(enabled_launchers | wc -l)" -lt 1 ]; then + echo "More than one launcher is currently enabled!" + echo "Enabled launchers: ${current_launcher}" + exit 1 + fi +} +check_launcher_has_app() { + if ! query "$1" apps | grep -q "$2"; then + echo "Unknown application: ${2}" + exit 1 + fi +} +case "$1" in + help | --help) + help + ;; + logs) + if [ $# -gt 2 ]; then + echo "Too many arguments" + exit 1 + elif [ $# -eq 2 ] && [[ "$2" != "-f" ]] && [[ "$2" != "--follow" ]]; then + echo "Invalid arguments" + exit 1 + fi + check_enabled_launchers + query "$(enabled_launchers)" "$@" + ;; + status) + if [ $# -gt 1 ]; then + echo "Too many arguments" + exit 1 + fi + check_enabled_launchers + current_launcher="$(enabled_launchers)" + echo -e "Launcher: \033[1m${current_launcher}\e[0m" + echo -ne "Status: \033[1m" + if query "$current_launcher" is-active; then + echo -ne "\e[32mrunning" + else + echo -ne "\e[31minactive" + fi + echo -e "\e[0m" + echo -n "Apps: $(query "$current_launcher" running | wc -l) running " + echo "$(query "$current_launcher" apps | wc -l) installed" + ;; + list-launchers) + launchers + ;; + switch-launcher) + if [ $# -lt 2 ]; then + echo "Too few arguments" + exit 1 + elif [ $# -gt 3 ]; then + echo "Too many arguments" + exit 1 + elif [ $# -eq 3 ] && [[ "$2" != "--start" ]]; then + echo "Invalid arguments" + exit 1 + fi + if [ $# -eq 3 ]; then + start=true + shift + else + start=false + fi + if ! [ -f "${data_dir}/${2}" ]; then + echo "${2} is not installed" + exit 1 + fi + enabled_launchers | while read -r launcher; do + if [[ "$launcher" != "$2" ]]; then + query "$launcher" disable + fi + done + if ! query "$2" is-enabled; then + query "$2" enable + fi + if $start; then + "$0" start-launcher + fi + ;; + start-launcher) + check_enabled_launchers + current_launcher="$(enabled_launchers)" + active_launchers | while read -r launcher; do + if [[ "$launcher" != "$current_launcher" ]]; then + query "$launcher" stop + fi + done + if query "$current_launcher" is-active; then + echo "Already started!" + exit + fi + query "$current_launcher" start + ;; + stop-launcher) + active_launchers | while read -r launcher; do + query "$launcher" stop + done + ;; + list-apps) + check_enabled_launchers + query "$(enabled_launchers)" apps + ;; + list-running-apps) + check_enabled_launchers + query "$(enabled_launchers)" running + ;; + list-paused-apps) + check_enabled_launchers + query "$(enabled_launchers)" paused + ;; + start-app) + check_enabled_launchers + launcher="$(enabled_launchers)" + check_launcher_has_app "$launcher" "$2" + query "$launcher" launch "$2" + ;; + stop-app) + check_enabled_launchers + launcher="$(enabled_launchers)" + check_launcher_has_app "$launcher" "$2" + query "$launcher" close "$2" + ;; + pause-app) + check_enabled_launchers + launcher="$(enabled_launchers)" + check_launcher_has_app "$launcher" "$2" + query "$launcher" pause "$2" + ;; + resume-app) + check_enabled_launchers + launcher="$(enabled_launchers)" + check_launcher_has_app "$launcher" "$2" + query "$launcher" resume "$2" + ;; + is-current-launcher) + check_enabled_launchers + if [[ "$(enabled_launchers)" != "$2" ]]; then + exit 1 + fi + ;; + is-enabled-launcher) + query "$2" is-enabled + ;; + is-active-launcher) + query "$2" is-active + ;; + *) + help + exit 1 + ;; +esac diff --git a/package/launcherctl/package b/package/launcherctl/package new file mode 100644 index 000000000..7a7743845 --- /dev/null +++ b/package/launcherctl/package @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Copyright (c) 2023 The Toltec Contributors +# SPDX-License-Identifier: MIT + +pkgnames=(launcherctl) +pkgdesc="Manage your installed launcher" +url=https://toltec-dev.org/ +pkgver=0.0.1-2 +timestamp=2023-12-18T03:32Z +section="launcher" +maintainer="Eeems " +license=MIT + +source=( + launcherctl +) +sha256sums=( + SKIP +) + +package() { + install -D -m 744 -t "$pkgdir"/opt/bin "$srcdir"/launcherctl + install -d "$pkgdir"/opt/share/launcherctl +} + +configure() { + echo "" + echo "You can use launcherctl to manage your active launcher" + echo "" +} + +preremove() { + launcherctl switch-launcher --start xochitl +} diff --git a/package/linux-mainline/package b/package/linux-mainline/package index 9838b9ead..8f8aa87da 100644 --- a/package/linux-mainline/package +++ b/package/linux-mainline/package @@ -2,11 +2,11 @@ # Copyright (c) 2021 The Toltec Contributors # SPDX-License-Identifier: MIT -archs=(rm2) +archs=(rm2os2) pkgnames=(linux-mainline) pkgdesc="reMarkable 2 kernel based on the mainline kernel" url=https://www.kernel.org -pkgver=6.2.0-2 +pkgver=6.2.0-3 timestamp=2022-05-22T21:50:09Z section=kernel maintainer="Alistair Francis " diff --git a/package/neofetch/package b/package/neofetch/package index ae1da866a..54cff1ae6 100644 --- a/package/neofetch/package +++ b/package/neofetch/package @@ -5,18 +5,18 @@ pkgnames=(neofetch) pkgdesc="A command-line system information tool" url="https://github.com/rM-self-serve/neofetch-rM" -pkgver=1.1.0-1 -timestamp=2023-12-06T11:43:00Z +pkgver=1.1.1-1 +timestamp=2024-03-14T11:43:00Z section="utils" maintainer="rM-self-serve <122753594+rM-self-serve@users.noreply.github.com>" license=MIT source=( - https://github.com/rM-self-serve/neofetch-rM/archive/955997e4e3b8be682f40ee54366e44337df68959.zip + "$url"/archive/6dfc7a7b0c10f451bdd8a09813ab6dea01ef6be2.zip ) sha256sums=( - 451017bd2517cf8c124af772e77b316ad784507709219e5831b28f613830f7e5 + 798ddbcb196b382e6bb70b3da08bc0e745c8b6da0bfe4ea5cd66653d383e5b1d ) package() { diff --git a/package/netevent/package b/package/netevent/package index d30293bf8..e1efee9ab 100644 --- a/package/netevent/package +++ b/package/netevent/package @@ -5,8 +5,8 @@ pkgnames=(netevent) pkgdesc="Input-Event device cloning utility" url="https://github.com/Blub/netevent" -pkgver=2.2.1-1 -timestamp=2021-12-03T19:43:04+01:00 +pkgver=2.2.2-1 +timestamp=2023-04-29T14:21:02Z section=utils maintainer="Salvatore Stella " license=GPL-2.0-only @@ -16,7 +16,7 @@ source=( "https://github.com/Blub/netevent/archive/refs/tags/${pkgver%-*}.tar.gz" ) sha256sums=( - ba1289cc04aef563baa9cc203111af3980a9311442233ffcf76760cda9f6aa69 + 09c0e97cd5c2cf5ed51e44ce955cc28cfa2cd0022bd48241f1096bc441439d3a ) build() { diff --git a/package/open-remarkable-shutdown/package b/package/open-remarkable-shutdown/package index 6a138346c..5c31ca592 100644 --- a/package/open-remarkable-shutdown/package +++ b/package/open-remarkable-shutdown/package @@ -2,10 +2,11 @@ # Copyright (c) 2021 The Toltec Contributors # SPDX-License-Identifier: MIT +archs=(rmallos2) pkgnames=(open-remarkable-shutdown) pkgdesc="Use remarkable-splash to display shutdown and reboot images" url=https://github.com/ddvk/remarkable-splash -pkgver=1.0-1 +pkgver=1.0-2 timestamp=2022-02-28T00:12Z section="utils" maintainer="Eeems " diff --git a/package/oxide/launcherctl-oxide b/package/oxide/launcherctl-oxide new file mode 100755 index 000000000..97ff4a73e --- /dev/null +++ b/package/oxide/launcherctl-oxide @@ -0,0 +1,57 @@ +#!/bin/bash +set -e +case "$1" in + is-active) + systemctl is-active --quiet tarnish.service + ;; + is-enabled) + systemctl is-enabled --quiet tarnish.service + ;; + logs) + if [ $# -eq 2 ] && [[ "$2" == "-f" ]] || [[ "$2" == "--follow" ]]; then + journalctl --follow --all --unit tarnish.service + else + journalctl --no-pager --all --unit tarnish.service + fi + ;; + start) + systemctl start tarnish.service + ;; + stop) + systemctl stop tarnish.service + ;; + enable) + systemctl enable tarnish.service + ;; + disable) + systemctl disable tarnish.service + ;; + apps) + rot apps get applications | jq -r 'keys | .[]' + ;; + running) + rot apps get runningApplications | jq -r 'keys | .[]' + ;; + paused) + rot apps get pausedApplications | jq -r 'keys | .[]' + ;; + launch | resume) + rot apps get applications \ + | jq -cr ".$2" | sed 's|/codes/eeems/oxide1/||' \ + | xargs -I {} rot --object Application:{} apps call launch + ;; + close) + rot apps get applications \ + | jq -cr ".$2" | sed 's|/codes/eeems/oxide1/||' \ + | xargs -I {} rot --object Application:{} apps call stop + ;; + pause) + rot apps get applications \ + | jq -cr ".$2" | sed 's|/codes/eeems/oxide1/||' \ + | xargs -I {} rot --object Application:{} apps call pause + ;; + *) + echo "Oxide does not support this method" + exit 1 + ;; +esac diff --git a/package/oxide/package b/package/oxide/package index 66a6575e4..83e0c27ab 100644 --- a/package/oxide/package +++ b/package/oxide/package @@ -4,7 +4,7 @@ pkgnames=(oxide oxide-extra oxide-utils inject_evdev liboxide liboxide-dev libsentry) _oxidever=2.7 -pkgver=$_oxidever-3 +pkgver=$_oxidever-7 _sentryver=0.5.0 timestamp=2023-12-05T04:43:04Z maintainer="Eeems " @@ -15,10 +15,12 @@ image=qt:v3.1 source=( "https://github.com/Eeems-Org/oxide/archive/refs/tags/v$_oxidever.zip" toltec-rm2-override.conf + launcherctl-oxide ) sha256sums=( e1f20fc60ae8edccb941e09c0e61cbfb58f1f8a5f64be98870eb2d079f83316f SKIP + SKIP ) build() { @@ -30,7 +32,7 @@ build() { oxide() { pkgdesc="Launcher application" section="launchers" - installdepends=("oxide-utils=$pkgver" "liboxide=$pkgver" "libsentry=$_sentryver" "reboot-guard") + installdepends=("oxide-utils=$pkgver" "liboxide=$pkgver" "libsentry=$_sentryver" "reboot-guard" "jq") replaces=(erode tarnish decay corrupt) conflicts=(erode tarnish decay corrupt) @@ -55,20 +57,26 @@ oxide() { # Task switcher install -D -m 755 -t "$pkgdir"/opt/bin "$srcdir"/release/opt/bin/corrupt install -D -m 644 -t "$pkgdir"/opt/usr/share/applications "$srcdir"/release/opt/usr/share/applications/codes.eeems.corrupt.oxide + # launcherctl registration + install -D -T -m 755 "$srcdir"/launcherctl-oxide "$pkgdir"/opt/share/launcherctl/oxide } configure() { systemctl daemon-reload - if ! is-enabled "tarnish.service"; then + + if ! launcherctl is-current-launcher oxide; then echo "" - echo "Run the following command(s) to use $pkgname as your launcher" - how-to-enable "tarnish.service" + echo "Run the following command(s) to use oxide as your launcher" + echo "launcherctl switch-launcher --start oxide" echo "" fi } preremove() { - disable-unit tarnish.service + # Just in case more than one launcher is active, do individual checks + if launcherctl is-active-launcher oxide || launcherctl is-enabled-launcher oxide; then + launcherctl switch-launcher --start xochitl + fi } postremove() { diff --git a/package/remarkable-stylus/package b/package/remarkable-stylus/package index 6d374e4fa..d54f87f97 100644 --- a/package/remarkable-stylus/package +++ b/package/remarkable-stylus/package @@ -2,8 +2,9 @@ # Copyright (c) 2021 The Toltec Contributors # SPDX-License-Identifier: MIT +archs=(rmallos2) pkgnames=(remarkable-stylus) -pkgver=0.0.3-2 +pkgver=0.0.3-3 pkgdesc="Generate a key press upon pressing the button of a Lamy AL-star EMR pen" timestamp=2020-11-19T20:07:29Z maintainer="Eeems " diff --git a/package/rmkit/launcherctl-remux b/package/rmkit/launcherctl-remux new file mode 100755 index 000000000..d0c1e5436 --- /dev/null +++ b/package/rmkit/launcherctl-remux @@ -0,0 +1,167 @@ +#!/bin/bash +set -e +remux_pid() { + systemctl show --no-pager --property MainPID remux.service | sed 's|MainPID=||' +} +remux_ppid() { + grep "PPid:" "/proc/$(remux_pid)/status" | awk '{print $2}' +} +draft_apps() { + find {/opt,}/etc/draft -maxdepth 1 -type f | while read -r file; do + name="$(grep 'name=' "$file" | sed 's|^name=||')" + call="$(grep 'call=' "$file" | sed 's|^call=||')" + echo -e "${name}\t${call}" + done +} +running_remux_apps() { + /opt/libexec/ps-procps-ng --ppid "$(remux_ppid)" -o pid,state,args | tail -n +2 | while read -r info; do + if [[ "$(echo "$info" | awk '{print $2}')" != "$1" ]]; then + continue + fi + pid="$(echo "$info" | awk '{print $1}')" + cmdline="$(echo "$info" | awk '{for (i=3; i<=NF; i++) print $i}')" + draft_apps | while read -r info; do + name="$(echo "$info" | cut -f1)" + if [[ "$name" == "xochitl" ]]; then + if [[ "$(realpath "/proc/${pid}/exe")" == "/usr/bin/xochitl" ]]; then + echo "$name" + break + fi + fi + call="$(echo "$info" | cut -f2)" + if [[ "$cmdline" == "$call" ]]; then + echo "$name" + break + fi + if ! [ -f "$call" ]; then + continue + fi + if [[ "$(realpath "/proc/${pid}/exe")" == "$(realpath "$call")" ]]; then + echo "$name" + break + fi + done + done +} +kill_pid() { + pid="$1" + if [[ "$(awk '{print $3}' "/proc/${pid}/stat")" == "T" ]]; then + kill -CONT "$pid" + fi + kill -TERM "$pid" + # Wait 5s for process to exit + start="$(date +'%s')" + while kill -0 "$pid" 2> /dev/null; do + sleep 0.5 + if [ "$(date +'%s')" -gt $((start + 5)) ]; then + break + fi + done + if kill -0 "$pid" 2> /dev/null; then + # If process is still running, force kill it + kill -KILL "$pid" + fi +} +case "$1" in + is-active) + systemctl is-active --quiet remux.service + ;; + is-enabled) + systemctl is-enabled --quiet remux.service + ;; + logs) + if [ $# -eq 2 ] && [[ "$2" == "-f" ]] || [[ "$2" == "--follow" ]]; then + journalctl --follow --all --unit remux.service + else + journalctl --no-pager --all --unit remux.service + fi + ;; + start) + systemctl start remux.service + ;; + stop) + systemctl stop remux.service + ;; + enable) + systemctl enable remux.service + ;; + disable) + systemctl disable remux.service + ;; + apps) + find {/opt,}/etc/draft -maxdepth 1 -type f | while read -r file; do + grep 'name=' "$file" | sed 's|^name=||' + done + ;; + running) + running_remux_apps S + ;; + paused) + running_remux_apps T + ;; + launch | resume) + echo "launch $2" > /run/remux.api + ;; + close) + draft_apps | while read -r info; do + name="$(echo "$info" | cut -f1)" + if [[ "$name" != "$2" ]]; then + continue + fi + call="$(echo "$info" | cut -f2)" + /opt/libexec/ps-procps-ng --ppid "$(remux_ppid)" -o pid,args | tail -n +2 | while read -r info; do + pid="$(echo "$info" | awk '{print $1}')" + if [[ "$name" == "xochitl" ]]; then + if [[ "$(realpath "/proc/${pid}/exe")" == "/usr/bin/xochitl" ]]; then + kill_pid "$pid" + continue + fi + fi + cmdline="$(echo "$info" | awk '{for (i=2; i<=NF; i++) print $i}')" + if [[ "$cmdline" == "$call" ]]; then + kill_pid "$pid" + continue + fi + if ! [ -f "$call" ]; then + continue + fi + if [[ "$(realpath "/proc/${pid}/exe")" == "$(realpath "$call")" ]]; then + kill_pid "$pid" + fi + done + done + ;; + pause) + draft_apps | while read -r info; do + name="$(echo "$info" | cut -f1)" + if [[ "$name" != "$2" ]]; then + continue + fi + call="$(echo "$info" | cut -f2)" + /opt/libexec/ps-procps-ng --ppid "$(remux_ppid)" -o pid,args | tail -n +2 | while read -r info; do + pid="$(echo "$info" | awk '{print $1}')" + if [[ "$name" == "xochitl" ]]; then + if [[ "$(realpath "/proc/${pid}/exe")" == "/usr/bin/xochitl" ]]; then + kill -STOP "$pid" + continue + fi + fi + cmdline="$(echo "$info" | awk '{for (i=2; i<=NF; i++) print $i}')" + if [[ "$cmdline" == "$call" ]]; then + kill -STOP "$pid" + continue + fi + if ! [ -f "$call" ]; then + continue + fi + if [[ "$(realpath "/proc/${pid}/exe")" == "$(realpath "$call")" ]]; then + kill -STOP "$pid" + fi + done + done + ;; + *) + echo "Remux does not support this method" + exit 1 + ;; +esac diff --git a/package/rmkit/package b/package/rmkit/package index 2b3da328a..43db913e2 100644 --- a/package/rmkit/package +++ b/package/rmkit/package @@ -14,11 +14,13 @@ source=( https://github.com/rmkit-dev/rmkit/archive/7edc291646c4a72b7b8a512205646a9ad6586fd6.zip remux.service genie.service + launcherctl-remux ) sha256sums=( 2861ea61ef272acd0d1d9ec4c80f44ef620be3f8ce58a356fbcbdb27e01dc9e8 SKIP SKIP + SKIP ) build() { @@ -145,27 +147,33 @@ nao() { remux() { pkgdesc="Launcher that supports multi-tasking applications" url="https://rmkit.dev/apps/remux" - pkgver=0.3.0-1 + pkgver=0.3.0-4 section="launchers" + installdepends=(procps-ng-ps) + package() { install -D -m 755 "$srcdir"/src/build/remux "$pkgdir"/opt/bin/remux install -D -m 644 "$srcdir"/remux.service "$pkgdir"/lib/systemd/system/remux.service + install -D -T -m 755 "$srcdir"/launcherctl-remux "$pkgdir"/opt/share/launcherctl/"$pkgname" } configure() { systemctl daemon-reload - if ! is-enabled "$pkgname.service"; then + if ! launcherctl is-current-launcher "$pkgname"; then echo "" echo "Run the following command(s) to use $pkgname as your launcher" - how-to-enable "$pkgname.service" + echo "launcherctl switch-launcher --start $pkgname" echo "" fi } preremove() { - disable-unit "$pkgname.service" + # Just in case more than one launcher is active, do individual checks + if launcherctl is-active-launcher "$pkgname" || launcherctl is-enabled-launcher "$pkgname"; then + launcherctl switch-launcher --start xochitl + fi } postremove() { diff --git a/package/signature-rm/package b/package/signature-rm/package index 7c24d8061..87154993a 100644 --- a/package/signature-rm/package +++ b/package/signature-rm/package @@ -2,17 +2,18 @@ # Copyright (c) 2021 The Toltec Contributors # SPDX-License-Identifier: MIT -_pkgname='signature-rm' -pkgnames=("$_pkgname") +archs=(rmallos2 rmallos3) +pkgnames=("signature-rm") pkgdesc="Remove the signature from the bottom of emails" url="https://github.com/rM-self-serve/signature-rM" -pkgver=1.0.2-1 +pkgver=1.0.2-2 timestamp=2023-12-06T11:43:00Z section="utils" maintainer="rM-self-serve <122753594+rM-self-serve@users.noreply.github.com>" license=MIT image=rust:v3.1 -conflicts=(ddvk-hacks webinterface-onboot) +conflicts=(webinterface-onboot) +conflicts_rmallos2=(ddvk-hacks) source=( "$url"/archive/b5561af4eb6a0f5aa6e98e1a1279066f0c4bd9b7.zip @@ -27,10 +28,10 @@ build() { package() { install -D -m 755 -t "$pkgdir"/opt/bin \ - "$srcdir/target/armv7-unknown-linux-gnueabihf/release/$_pkgname" + "$srcdir/target/armv7-unknown-linux-gnueabihf/release/$pkgname" - touch "$srcdir"/emptyfile - install -D -m 666 -t "$pkgdir"/usr/share/toltec/reenable.d/"$_pkgname" "$srcdir"/emptyfile + mkdir -p "$pkgdir"/opt/share/toltec/reenable.d + touch "$pkgdir"/opt/share/toltec/reenable.d/"$pkgname" } configure() { diff --git a/package/sudoku/package b/package/sudoku/package index 1807fbda7..24e7c8957 100644 --- a/package/sudoku/package +++ b/package/sudoku/package @@ -5,8 +5,8 @@ pkgnames=(sudoku) pkgdesc="Sudoku for Remarkable" url="https://github.com/HookedBehemoth/remarkable-sudoku" -pkgver=0.1.1-1 -timestamp=2023-01-05T03:15Z +pkgver=0.1.2-1 +timestamp=2023-02-04T22:49Z section="games" maintainer="Luis S. " license=GPL-3.0-only @@ -15,7 +15,7 @@ flags=(patch_rm2fb) image=rust:v3.1 source=("https://github.com/HookedBehemoth/remarkable-sudoku/archive/refs/tags/v${pkgver%-*}.tar.gz") -sha256sums=(c3d9e941d0d837b90d376104eec7693f6b609010662d7e9b5ae57570648d8856) +sha256sums=(08a801a6ffc3f328fc92c8aebadbcc7a123b1abebf5cbe276d5f9f52058ee864) build() { cargo build --release diff --git a/package/templatectl/package b/package/templatectl/package index 7c7414550..b09b7fc7b 100644 --- a/package/templatectl/package +++ b/package/templatectl/package @@ -5,7 +5,7 @@ pkgnames=(templatectl) pkgdesc="Tool to add/remove templates for xochitl" url=https://github.com/PeterGrace/templatectl -pkgver=0.1.3-4 +pkgver=0.1.3-5 timestamp=2021-01-15T01:23Z section="templates" maintainer="Peter Grace " @@ -22,6 +22,8 @@ build() { package() { install -D -m 755 -t "$pkgdir"/opt/bin \ "$srcdir"/target/armv7-unknown-linux-gnueabihf/release/templatectl + mkdir -p "$pkgdir"/opt/share/toltec/reenable.d + touch "$pkgdir"/opt/share/toltec/reenable.d/"$pkgname" } preinstall() { diff --git a/package/toltec-base/package b/package/toltec-base/package index 06d812667..183cb2995 100644 --- a/package/toltec-base/package +++ b/package/toltec-base/package @@ -2,25 +2,26 @@ # Copyright (c) 2023 The Toltec Contributors # SPDX-License-Identifier: MIT -archs=(rm1 rm2) +archs=(rmall rmallos2 rmallos3 rm1 rm1os2 rm1os3 rm2 rm2os2 rm2os3) pkgnames=(toltec-base) pkgdesc="Metapackage defining the base set of packages in a Toltec install" url=https://toltec-dev.org/ -pkgver=1.3-1 +pkgver=1.3-4 timestamp=2023-12-27T08:30Z section="utils" maintainer="Eeems " license=MIT -installdepends=(toltec-bootstrap toltec-completion) -installdepends_rm1=(open-remarkable-shutdown) -installdepends_rm2=(rm2-suspend-fix) +installdepends=(toltec-bootstrap toltec-deletions toltec-completion launcherctl wget-ssl ca-certificates entware-rc) +installdepends_rm1os2=(open-remarkable-shutdown) +installdepends_rm1os3=(open-remarkable-shutdown) +installdepends_rm2os2=(rm2-suspend-fix) +installdepends_rm2os3=(rm2-suspend-fix) source=() sha256sums=() package() { - touch "$srcdir"/emptyfile - install -D -m 666 -t "$pkgdir"/usr/share/toltec/reenable.d/toltec-base "$srcdir"/emptyfile + true } configure() { @@ -31,23 +32,28 @@ configure() { /opt/etc/profile echo "Disabling automatic update" disable-unit update-engine.service - if [[ "$arch" == "rm1" ]]; then - echo "Disabling usb1 network device to avoid long boots" - if ! is-masked sys-subsystem-net-devices-usb1.device; then - systemctl mask sys-subsystem-net-devices-usb1.device - fi - if ! is-masked busybox-ifplugd@usb1.service; then - systemctl mask busybox-ifplugd@usb1.service - fi - elif [[ "$arch" == "rm2" ]]; then - echo "Enabling usb1 network device to ensure usb SSH works" - if is-masked sys-subsystem-net-devices-usb1.device; then - systemctl unmask sys-subsystem-net-devices-usb1.device - fi - if is-masked busybox-ifplugd@usb1.service; then - systemctl unmask busybox-ifplugd@usb1.service - fi - fi + case "$arch" in + rmall | rmallos2 | rmallos3) + echo "Warning: rmall version of toltec-base should not be installed" + echo "Please run opkg install --force-reinstall toltec-base" + ;; + rm1 | rm1os2 | rm1os3) + if ! is-masked sys-subsystem-net-devices-usb1.device; then + systemctl mask sys-subsystem-net-devices-usb1.device + fi + if ! is-masked busybox-ifplugd@usb1.service; then + systemctl mask busybox-ifplugd@usb1.service + fi + ;; + rm2 | rm2os2 | rm2os3) + if is-masked sys-subsystem-net-devices-usb1.device; then + systemctl unmask sys-subsystem-net-devices-usb1.device + fi + if is-masked busybox-ifplugd@usb1.service; then + systemctl unmask busybox-ifplugd@usb1.service + fi + ;; + esac } postremove() { diff --git a/package/toltec-bootstrap/package b/package/toltec-bootstrap/package index 1b033cc4a..8c95c296b 100644 --- a/package/toltec-bootstrap/package +++ b/package/toltec-bootstrap/package @@ -5,8 +5,8 @@ pkgnames=(toltec-bootstrap) pkgdesc="Manage your Toltec install" url=https://toltec-dev.org/ -pkgver=0.2.3-1 -timestamp=2023-09-17T17:35Z +pkgver=0.4.1-1 +timestamp=2023-11-27T00:34Z section="utils" maintainer="Eeems " license=MIT @@ -53,14 +53,14 @@ configure() { fi create-entware-conf - switch-branch "$branch" - echo "Your Opkg configuration has been migrated" + fi - if generate-opkg-conf; then - echo - echo "! The upgrade is not finished! Please run \`opkg update\`" - echo "! and \`opkg upgrade\` once more to complete it." - echo - fi + switch-branch "$(get-branch)" + echo "Your Opkg configuration has been upgraded" + if generate-opkg-conf; then + echo + echo "! The upgrade is not finished! Please run \`opkg update\`" + echo "! and \`opkg upgrade\` once more to complete it." + echo fi } diff --git a/package/toltec-bootstrap/toltecctl b/package/toltec-bootstrap/toltecctl index b9ea0bcb3..b6ba832bf 100644 --- a/package/toltec-bootstrap/toltecctl +++ b/package/toltec-bootstrap/toltecctl @@ -10,9 +10,16 @@ toltec_src=/home/root/.entware # Path where Toltec is mounted toltec_dest=/opt +# Path where toltec caches compatibility information +toltec_share=/home/root/.local/share/toltec +# Path to static opkg build +opkg_path=/home/root/.local/bin/opkg +# Path to opkg install status file +opkg_status="/opt/lib/opkg/status" + # Path to Opkg configuration -opkg_conf="$toltec_dest"/etc/opkg.conf -opkg_conf_dir="$toltec_dest"/etc/opkg.conf.d +opkg_conf="$toltec_src"/etc/opkg.conf +opkg_conf_dir="$toltec_src"/etc/opkg.conf.d # Path to the Xochitl configuration xochitl_conf=/home/root/.config/remarkable/xochitl.conf @@ -27,6 +34,50 @@ bashrc_start_marker="# Added by Toltec bootstrap (do not modify!)" bashrc_old_start_marker="# Path added by Toltec bootstrap" bashrc_end_marker="# End of Toltec bootstrap additions" +# Print a log message +# +# Arguments: +# +# [$1] - Log level: INFO, WARN or ERROR (default: INFO) +# $2... - Messages to print, each argument goes to a separate line +log() { + # Output stream where the messages will be sent + local log_type="INFO" + local fd=1 + local colored_prefix + + if [[ $# -ge 2 ]]; then + case "$1" in + INFO | WARN | ERROR) + log_type="$1" + shift + ;; + esac + fi + + case "$log_type" in + INFO) colored_prefix='\e[32mINFO:\e[0m ' ;; + WARN) + colored_prefix='\e[33mWARN:\e[0m ' + fd=2 + ;; + ERROR) + colored_prefix='\e[31mERROR:\e[0m ' + fd=2 + ;; + esac + + echo -e "${colored_prefix}$1" >&$fd + + # Extra lines to print indented + shift + local line + + for line in "$@"; do + echo -e " $line" >&$fd + done +} + # Identify which reMarkable model we’re currently running on # # Output: One of the following strings @@ -51,6 +102,68 @@ identify-model() { esac } +# Find the current OS release version +# +# Output: Current version in the X.Y.Z.P format +get-release-version() { + awk -F= '/RELEASE_VERSION/{print $2}' /usr/share/remarkable/update.conf +} + +# Check to see if the version is supported and error if it isn't supported +# +# Arguments: +# +# $1 - Branch for which to check support +# +# Exit code: +# +# 0 - if the current version is supported +# 1 - if unsupported +# 2 - if version compatibility information could not be retrieved +# 3 - unable to install standalone wget +check-version() { + local wget + if [[ "$(install-state)" != "yes" ]] || [[ "$(command -v wget)" != "/opt/bin/wget" ]]; then + if ! install-standalone-wget; then + return 2 + fi + wget="${toltec_share}/wget" + else + wget="wget" + fi + local check_branch + local current_model + local current_version + local cwd + check_branch="$1" + current_model="$(identify-model)" + current_version="$(get-release-version)" + + cwd="$(pwd)" + mkdir -p "$toltec_share" + cd "$toltec_share" + if ! "$wget" "$toltec_srv_root"/"$check_branch"/Compatibility \ + --timestamping \ + --no-verbose \ + --ignore-length 2> /dev/null; then + log ERROR "Unable to fetch updated version compatibility information, make sure you have a stable Wi-Fi connection" + if ! [ -f Compatibility ]; then + cd "$cwd" + return 2 + fi + log WARN "Using outdated cached version compatibility information" + fi + cd "$cwd" + + if ! grep -q "${current_model}=${current_version}" "${toltec_share}/Compatibility"; then + LOG ERROR "You’re running an unsupported OS version: $current_version" + LOG ERROR "Please monitor Toltec releases for upcoming support" + return 1 + fi + + return 0 +} + # Get the password used to login to the SSH prompt # # Output: SSH password @@ -122,21 +235,214 @@ remove-bind-mount() { if [[ ! -e $unit_path ]]; then echo "No existing bind mount for '$1'" - return 1 + return fi echo "Removing mount over '$1'" systemctl disable "$unit_name" - umount -l "$1" + systemctl stop "$unit_name" + if mountpoint -q "$1"; then + umount -l "$1" + fi rm "$unit_path" systemctl daemon-reload } +# Escape a string for use in a sed search +# +# Arguments +# +# $1 - String to escape +# +# Output: +# +# Escaped string +escape-for-sed() { + # shellcheck disable=SC1003 + sed -e 's/[^^]/[&]/g; s/\^/\\^/g; $!a\'$'\n''\\n' <<< "$1" | tr -d '\n' +} + +# Escape a string for use in a sed replacement +# +# Arguments +# +# $1 - String to escape +# +# Output: +# +# Escaped string +escape-for-sed-replace() { + IFS= read -d '' -r < <(sed -e ':a' -e '$!{N;ba' -e '}' -e 's/[&/\]/\\&/g; s/\n/\\&/g' <<< "$1") + printf %s "${REPLY%$'\n'}" +} + +# Replace multiline string content in stdin +# +# Arguments: +# +# $1 - String to replace +# $2 - string to replace with +# stdin - Text to perform replacement on +# +# Output: +# +# Contents of stdin with the string replaced +replace-string() { + sed \ + -e ':a' \ + -e '$!{N;ba' -e '}' \ + -e "s/$(escape-for-sed "$1")/$(escape-for-sed-replace "$2")/" +} + +# Get the opkg status for a package +# +# Arguments: +# +# $1 - Package name +# +# Output: Opkg status information for the package +# +# Exit Code: +# +# 0 - Status found +# 1 - Status not found +get-package-status() { + local status + status="$(opkg status "$1" | grep -v "has no valid architecture, ignoring" || true)" + if [ -n "$status" ]; then + echo "$status" + return 0 + fi + local index + local index2 + local count + # Don't use --line-number so this works on the built in grep + index="$(grep -n "Package: ${1}" "$opkg_status" | cut -d':' -f1 || echo "-1")" + if [ "$index" -eq -1 ]; then + return 1 + fi + # Don't use --line-number so this works on the built in grep + count="$(tail -n +$((index + 1)) "$opkg_status" | grep -n "Package: " | head -n1 | cut -d':' -f1 || echo "-1")" + if [ "$count" -eq -1 ]; then + return 1 + fi + index2=$((index + count - 1)) + status="$(sed -n "${index},${index2}p;$((index2 + 1))q" "$opkg_status")" + if [ -z "$status" ]; then + return 1 + fi + echo "$status" + return 0 +} + +# Check if a string appears in a set of strings +# +# Arguments: +# +# $1 - String to look for +# $2... - Elements to compare to $1 +# +# Example: +# +# > has-element "needle" "${haystack[@]}" +# Will return 0 if "needle" is found in the "haystack" array. +# +# Exit code: 0 if the element is found, 1 otherwise. +has-element() { + local needle="$1" + shift + + for element; do + if [[ $needle == "$element" ]]; then + return 0 + fi + done + + return 1 +} + +# Update the opkg status for a package with the correct architecture for the device +# +# Arguments: +# +# $1 - Package name +# +# Exit Codes: +# +# 0 - Package status was updated +# 1 - Package status was not modified +# 2 - Package status was not found +# 3 - Package status has no architecture +update-package-arch() { + if ! grep -q "Package: ${1}" "$opkg_status"; then + return 1 + fi + local arch + local model + local new_status + local version + local status + local rc=0 + status="$(get-package-status "$1" || true)" + if [ -z "$status" ]; then + log WARN "Unable to get status for package: ${1}" + return 2 + fi + arch="$(echo "$status" | grep "Architecture:" | awk '{print $2}')" + if [ -z "$arch" ]; then + return 3 + fi + case "$arch" in + rmallos2 | rmallos3) + version="$(identify-support-version)" + new_status="$(echo "$status" | replace-string "Architecture: ${arch}" "Architecture: rmall${version}")" + ;; + rm1os2 | rm1os3 | rm2os2 | rm2os3) + model="$(identify-model)" + version="$(identify-support-version)" + new_status="$(echo "$status" | replace-string "Architecture: ${arch}" "Architecture: ${model}${version}")" + ;; + *) + new_status="$status" + ;; + esac + if [[ "$status" == "$new_status" ]]; then + return 1 + fi + echo "Updating package architecture for package: ${1}" + sed -i \ + -e ':a' \ + -e '$!{N;ba' -e '}' \ + -e "s/$(escape-for-sed "$status")/$(escape-for-sed-replace "$new_status")/" \ + "$opkg_status" + return 0 +} + +# Reinstall toltec-base and toltec-deletions +reinstall-base() { + local packages=() + while read -r pkg; do + if update-package-arch "$pkg"; then + packages+=("$pkg") + fi + done < <(opkg list-installed | grep -v "has no valid architecture, ignoring" | cut -d' ' -f1 || true) + while read -r pkg; do + if update-package-arch "$pkg"; then + packages+=("$pkg") + fi + done < <(opkg list-installed | grep "has no valid architecture, ignoring" | cut -d' ' -f2 || true) + if ! has-element "toltec-base" "${packages[@]}"; then + packages+=(toltec-base) + fi + if ! has-element "toltec-deletions" "${packages[@]}"; then + packages+=(toltec-deletions) + fi + opkg install --force-reinstall "${packages[@]}" || true +} + # Reinstall all Toltec packages that had files installed outside of # $toltec_src, e.g. systemd configuration files reinstall-root() { - opkg update - # Get the list of installed packages with files on root local pkgname declare -A on_root_packages @@ -161,7 +467,7 @@ reinstall-root() { # temporarily set +u if [[ ${#reinstall_packages[@]} -ne 0 ]]; then - opkg install --force-reinstall --force-remove "${!reinstall_packages[@]}" + opkg install --force-reinstall --force-remove "${!reinstall_packages[@]}" || true else echo "No package needs to be reinstalled" fi @@ -195,7 +501,7 @@ SHELL new_path="$(bash -l -c "echo \$PATH")" if [[ $old_path != "$new_path" ]]; then - echo "Please restart your SSH session or run 'exec bash --login' to use Toltec" + log WARN "Please restart your SSH session or run 'exec bash --login' to use Toltec" fi } @@ -267,6 +573,61 @@ src/gz entware https://bin.entware.net/armv7sf-k3.2 CONF } +# Get the current Toltec branch of this installation +# +# Output: Current branch name +get-branch() { + if ! [ -f "$opkg_conf_dir/15-toltec.conf" ]; then + return + fi + local srv_prefix_len=${#toltec_srv_root} + local srv_prefix="${toltec_srv_root//\//\\/}" + local awk_get_branch=" + match(\$0, /$srv_prefix\/(.+)\/rmall/) { + print substr( \ + \$0, \ + RSTART+$srv_prefix_len+1, \ + RLENGTH-$srv_prefix_len-1-6 \ + ) + } + " + awk "$awk_get_branch" "$opkg_conf_dir/15-toltec.conf" | head -n1 || true +} + +# Compare two version numbers +# +# Arguments: +# +# $1 - Version number to compare +# $2 - Version number to compare +# +# Output: True if the first number is larger than the second +compare-versions() { + [ "$(echo -e "${1}\n${2}" | sort | head -n1)" != "$1" ] +} + +# Identify which toltec version this should be limited to +# +# Output: One of the following strings +# +# os2 - 2.x OS version +# os3 - 3.x OS version +# unknown +identify-support-version() { + local current_version + current_version="$(get-release-version)" + + if compare-versions "2.0" "$current_version"; then + echo "unknown" + elif compare-versions "3.0" "$current_version"; then + echo "os2" + elif compare-versions "4.0" "$current_version"; then + echo "os3" + else + echo "unknown" + fi +} + # Set the Toltec branch for this installation # (generate-opkg-conf must be run afterwards to rebuild the main config file) # @@ -276,10 +637,16 @@ CONF switch-branch() { local branch="${1:-stable}" local model + local version model="$(identify-model)" + version="$(identify-support-version)" if [[ $model = "unknown" ]]; then - echo "You’re running an unsupported or unrecognised device" + log ERROR "You’re running an unsupported or unrecognised device" + exit 1 + fi + if [[ $version = "unknown" ]]; then + log ERROR "You're running an unsupported or unrecognised OS version" exit 1 fi @@ -292,16 +659,43 @@ switch-branch() { # switch to a different Toltec branch arch rmall 200 -src/gz toltec-rmall $toltec_srv_root/$branch/rmall -arch $model 250 -src/gz toltec-$model $toltec_srv_root/$branch/$model +src/gz toltec-rmall ${toltec_srv_root}/${branch}/rmall +arch ${model} 250 +src/gz toltec-${model} ${toltec_srv_root}/${branch}/${model} +arch rmall${version} 260 +src/gz toltec-rmall$version ${toltec_srv_root}/${branch}/rmall${version} +arch ${model}os2 270 +arch ${model}os3 270 +src/gz toltec-${model}${version} ${toltec_srv_root}/${branch}/${model}${version} CONF } # Re-enable Toltec install after system update reenable() { + log INFO "Mounting /opt" add-bind-mount "$toltec_src" "$toltec_dest" + switch-branch "$(get-branch)" + log INFO "Generating /opt/etc/opkg.conf" + generate-opkg-conf || true + log INFO "Opkg update" + opkg update + log INFO "Reinsalling base packages" + reinstall-base + log INFO "Reinstalling packages with files on the root partition" reinstall-root + if [ -d /opt/share/toltec/reenable.d ]; then + find /opt/share/toltec/reenable.d -maxdepth 1 -mindepth 1 -print0 \ + | xargs -0rn1 basename \ + | while read -r pkg; do + local script + script="/opt/lib/opkg/info/${pkg}.postinst" + if [ -f "$script" ]; then + log INFO "Reconfiguring ${pkg}" + "$script" configure || true + fi + done + fi + log INFO "Configuring bashrc" set-path } @@ -323,18 +717,68 @@ list-installed-ordered() { # tsort reports errors if there are dependency cycles, we ignore them } -# Remove Toltec completely -uninstall() { - # Fetch standalone opkg used to uninstall packages - local opkg_path=/home/root/.local/bin/opkg +# Install standalone opkg binary +install-standalone-opkg() { + local wget + if [[ "$(install-state)" != "yes" ]] || [[ "$(command -v wget)" != "/opt/bin/wget" ]]; then + if ! install-standalone-wget; then + return 2 + fi + wget="${toltec_share}/wget" + else + wget="wget" + fi local opkg_remote=https://bin.entware.net/armv7sf-k3.2/installer/opkg - if ! wget --no-verbose "$opkg_remote" --output-document "$opkg_path"; then - echo "Unable to fetch standalone opkg, make sure you have a stable Wi-Fi connection" + if ! "$wget" --no-verbose "$opkg_remote" --output-document "$opkg_path"; then + log ERROR "Unable to fetch standalone opkg, make sure you have a stable Wi-Fi connection" return 1 fi chmod u+x "$opkg_path" + if [[ $(command -v opkg) != "$opkg_path" ]]; then + export PATH + PATH="$(dirname "$opkg_path"):$PATH)" + fi +} + +# Install a local wget binary which supports TLS (the original one +# installed on the reMarkable does not) in the PATH +install-standalone-wget() { + local wget_path="${toltec_share}/wget" + local wget_remote=http://toltec-dev.org/thirdparty/bin/wget-v1.21.1 + local wget_checksum=8798fcdabbe560722a02f95b30385926e4452e2c98c15c2c217583eaa0db30fc + + if [ -f "$wget_path" ] && ! [[ -e $wget_path ]] || ! sha256sum -c <(echo "$wget_checksum $wget_path") > /dev/null 2>&1; then + rm "$wget_path" + fi + + if ! [ -f "$wget_path" ]; then + log INFO "Fetching secure wget" + + # Download and compare to hash + mkdir -p "$(dirname "$wget_path")" + + if ! wget -q "$wget_remote" --output-document "$wget_path"; then + log ERROR "Could not fetch wget, make sure you have a stable Wi-Fi connection" + exit 1 + fi + + if ! sha256sum -c <(echo "$wget_checksum $wget_path") > /dev/null 2>&1; then + log ERROR "Invalid checksum for the local wget binary" + exit 1 + fi + + chmod 755 "$wget_path" + fi +} + +# Remove Toltec completely +uninstall() { + # Fetch standalone opkg used to uninstall packages + if ! install-standalone-opkg; then + return 1 + fi # Remove installed packages in reverse dependency order list-installed-ordered | while read -r pkgname; do @@ -358,6 +802,71 @@ uninstall() { systemctl enable xochitl } +# The current toltec install state +# +# Output: +# +# yes - opt.mount is enabled and active +# partial - opt.mount is active but not enabled +# no - opt.mount is not enabled, or does not exist +install-state() { + local unit_name + local enabled + unit_name="$(systemd-escape --path "$toltec_dest").mount" + if ! systemctl --quiet is-enabled "$unit_name" 2> /dev/null; then + echo "no" + elif systemctl --quiet is-active "$unit_name"2 > /dev/null; then + echo "partial" + else + echo "yes" + fi +} + +# Output toltec installation status +status() { + echo -ne "Enabled: \033[1m" + local enabled=false + case "$(install-state)" in + yes) + enabled=true + echo -ne "\e[32mYes" + ;; + no) + echo -ne "\e[31mNo" + ;; + partial) + echo -ne "\e[33mPartial" + ;; + *) + echo -ne "\e[31mUnknown" + ;; + esac + echo -e "\e[0m" + echo -ne "Supported: \033[1m" + local rc + rc=0 + check-version "$(get-branch)" &> /dev/null || rc=$? + if [ $rc -eq 0 ]; then + echo -ne "\e[32mYes" + elif [ $rc -eq 2 ] || [ $rc -eq 3 ]; then + echo -ne "\e[33mUnknown" + else + echo -ne "\e[31mNo" + fi + echo -e "\e[0m" + echo -n "Branch: " + if [ -f "$opkg_conf" ]; then + # shellcheck disable=SC2005 + echo "$(get-branch)" + else + echo -e "\033[1m\e[33mUnknown\e[0m" + fi + echo -n "Model: " + identify-model + echo -n "OS: " + get-release-version +} + help() { echo "Usage: $(basename "$0") COMMAND Manage your Toltec install. Available commands: @@ -387,7 +896,7 @@ if [[ $0 = "${BASH_SOURCE[0]}" ]]; then echo if [[ $REPLY =~ ^[Nn]$ ]]; then - echo "Not reloading. Use 'opkg update' to do it manually." + log WARN "Not reloading. Use 'opkg update' to do it manually." else opkg update fi @@ -416,7 +925,13 @@ MSG echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then - echo "Canceled" + log WARN "Canceled" + exit 1 + fi + fi + + if ! check-version "$target_branch"; then + if [[ -z $force ]]; then exit 1 fi fi @@ -433,7 +948,7 @@ MSG echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then - echo "Canceled" + log WARN "Canceled" exit 1 fi fi @@ -446,7 +961,7 @@ MSG echo if [[ $REPLY =~ ^[Nn]$ ]]; then - echo "Not reloading. Use 'opkg update' to do it manually." + log WARN "Not reloading. Use 'opkg update' to do it manually." exit fi fi @@ -456,6 +971,14 @@ MSG ;; reenable) + force=$({ (($# > 0)) && [[ $1 = "--force" || $1 = "-f" ]] && echo 1; } || true) + + if ! check-version "$(get-branch)"; then + if [[ -z $force ]]; then + exit 1 + fi + fi + reenable ;; @@ -467,7 +990,7 @@ MSG echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then - echo "Canceled" + log WARN "Canceled" exit 1 fi fi @@ -479,17 +1002,21 @@ MSG echo if [[ $REPLY =~ ^[Nn]$ ]]; then - echo "Please reboot your device manually to complete the uninstall process" + log WARN "Please reboot your device manually to complete the uninstall process" exit fi fi if [[ ! -f $ssh_key_file ]]; then - echo "In case something goes wrong, your SSH password is: $(get-ssh-password)" + log WARN "In case something goes wrong, your SSH password is: $(get-ssh-password)" fi - echo "Rebooting" - reboot + log INFO "Rebooting" + systemctl reboot + ;; + + status) + status ;; help | -h | --help) @@ -497,7 +1024,7 @@ MSG ;; *) - echo -e "Error: Invalid command '$action'\n" + log ERROR "Invalid command '$action'\n" help exit 1 ;; diff --git a/package/toltec-completion/_launcherctl b/package/toltec-completion/_launcherctl new file mode 100644 index 000000000..66deee8ac --- /dev/null +++ b/package/toltec-completion/_launcherctl @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# Copyright (c) 2023 The Toltec Contributors +# SPDX-License-Identifier: MIT +# shellcheck disable=SC2016,SC2199,SC2207 + +_launcherctl() { + local cur prev words cword split + _init_completion -s || return + if [[ $cword -eq 1 ]]; then + COMPREPLY=($(compgen -W 'help status logs list-launchers switch-launcher start-launcher stop-launcher list-apps list-running-apps list-paused-apps start-app stop-app pause-app resume-app is-current-launcher is-enabled-launcher is-active-launcher' -- "$cur")) + return + fi + case ${words[1]} in + logs) + if [[ $cword -eq 2 ]]; then + COMPREPLY+=($(compgen -W "--follow" -- "$cur")) + fi + return + ;; + switch-launcher) + if [[ $cword -eq 2 ]]; then + COMPREPLY+=($(compgen -W "--start $(launcherctl list-launchers)" -- "$cur")) + elif [[ $cword -eq 3 ]]; then + COMPREPLY+=($(compgen -W "$(launcherctl list-launchers)" -- "$cur")) + fi + return + ;; + start-app) + if [[ $cword -eq 2 ]]; then + COMPREPLY+=($(compgen -W "$(launcherctl list-apps)" -- "$cur")) + fi + ;; + stop-app | pause-app) + if [[ $cword -eq 2 ]]; then + COMPREPLY+=($(compgen -W "$(launcherctl list-running-apps)" -- "$cur")) + fi + ;; + resume-app) + if [[ $cword -eq 2 ]]; then + COMPREPLY+=($(compgen -W "$(launcherctl list-paused-apps)" -- "$cur")) + fi + ;; + esac +} + +complete -F _launcherctl launcherctl diff --git a/package/toltec-completion/_rcctl b/package/toltec-completion/_rcctl new file mode 100644 index 000000000..7cefec693 --- /dev/null +++ b/package/toltec-completion/_rcctl @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Copyright (c) 2023 The Toltec Contributors +# SPDX-License-Identifier: MIT +# shellcheck disable=SC2016,SC2199,SC2207 + +_rcctl() { + local cur prev words cword split + _init_completion -s || return + if [[ $cword -eq 1 ]]; then + COMPREPLY=($(compgen -W 'help start stop restart enable disable status logs list' -- "$cur")) + return + fi + case ${words[1]} in + start | stop | restart | enable | disable | status) + if [[ $cword -eq 2 ]]; then + COMPREPLY+=($(compgen -W "$(rcctl list)" -- "$cur")) + fi + return + ;; + logs) + if [[ $cword -eq 2 ]]; then + COMPREPLY+=($(compgen -W "--follow $(rcctl list)" -- "$cur")) + elif [[ $cword -eq 3 ]]; then + COMPREPLY+=($(compgen -W "$(rcctl list)" -- "$cur")) + fi + return + ;; + esac +} + +complete -F _rcctl rcctl diff --git a/package/toltec-completion/_toltecctl b/package/toltec-completion/_toltecctl index e1d3b765b..5a8d7e01c 100755 --- a/package/toltec-completion/_toltecctl +++ b/package/toltec-completion/_toltecctl @@ -8,7 +8,7 @@ _toltecctl() { _init_completion -s || return if [[ $cword -eq 1 ]]; then - COMPREPLY=($(compgen -W 'help generate-opkg-conf switch-branch reenable uninstall' -- "$cur")) + COMPREPLY=($(compgen -W 'help generate-opkg-conf switch-branch reenable uninstall status' -- "$cur")) return fi diff --git a/package/toltec-completion/package b/package/toltec-completion/package index cc465a569..698f50c8b 100644 --- a/package/toltec-completion/package +++ b/package/toltec-completion/package @@ -5,7 +5,7 @@ pkgnames=(toltec-completion) pkgdesc="Expands bash-completion with functions for toltec-specific commands" url=https://github.com/toltec-dev/toltec -pkgver=0.3.1-1 +pkgver=0.4.0-2 timestamp=2022-01-23T23:29Z section="utils" maintainer="Linus K. " @@ -15,10 +15,14 @@ installdepends=(bash-completion) source=( _opkg _toltecctl + _launcherctl + _rcctl ) sha256sums=( SKIP SKIP + SKIP + SKIP ) package() { diff --git a/package/toltec-deletions/package b/package/toltec-deletions/package new file mode 100644 index 000000000..c3cea1e4b --- /dev/null +++ b/package/toltec-deletions/package @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# Copyright (c) 2023 The Toltec Contributors +# SPDX-License-Identifier: MIT + +archs=(rmallos2 rmallos3) +pkgnames=(toltec-deletions) +pkgdesc="Metapackage to handle package deletions between OS versions" +url=https://toltec-dev.org/ +pkgver=0.1-4 +timestamp=2023-12-03T04:51:58Z +section="utils" +maintainer="Eeems " +license=MIT +installdepends=(toltec-bootstrap) +conflicts_rmallos2=() +replaces_rmallos2=() +conflicts_rmallos3=( + ddvk-hacks + fuse + wireguard + innernet-client + gocryptfs + linux-mainline + remarkable-stylus + open-remarkable-shutdown +) +replaces_rmallos3=( + ddvk-hacks + fuse + wireguard + innernet-client + gocryptfs + linux-mainline + remarkable-stylus + open-remarkable-shutdown +) + +source=() +sha256sums=() + +package() { + # This should be fully reinstalled on reenable + # So add a file to root + mkdir -p "$pkgdir"/usr/share/toltec/reenable.d + touch "$pkgdir"/usr/share/toltec/reenable.d/toltec-deletions +} diff --git a/package/webinterface-localhost/package b/package/webinterface-localhost/package new file mode 100644 index 000000000..da657551a --- /dev/null +++ b/package/webinterface-localhost/package @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# Copyright (c) 2020 The Toltec Contributors +# SPDX-License-Identifier: MIT + +_pkgname="webinterface-localhost" +pkgnames=("$_pkgname") +pkgdesc="View the web interface if running, on localhost. Useful for tailscale." +url=https://toltec-dev.org/ +pkgver=0.0.0-1 +timestamp=2024-03-11T13:03:16Z +section="utils" +maintainer="rM-self-serve <122753594+rM-self-serve@users.noreply.github.com>" +license=MIT + +source=( + "$_pkgname.socket" + "$_pkgname.service" +) + +sha256sums=( + SKIP + SKIP +) + +package() { + install -D -m 644 -t "$pkgdir/lib/systemd/system" \ + "$srcdir/$_pkgname.socket" + install -D -m 644 -t "$pkgdir/lib/systemd/system" \ + "$srcdir/$_pkgname.service" +} + +configure() { + systemctl daemon-reload + + if is-active "$pkgname".socket; then + echo "Restarting $pkgname" + systemctl restart "$pkgname".socket + fi + + systemctl enable --now "$pkgname.socket" +} + +preremove() { + disable-unit "$pkgname.socket" +} + +postremove() { + systemctl daemon-reload +} diff --git a/package/webinterface-localhost/webinterface-localhost.service b/package/webinterface-localhost/webinterface-localhost.service new file mode 100644 index 000000000..bf93761a3 --- /dev/null +++ b/package/webinterface-localhost/webinterface-localhost.service @@ -0,0 +1,8 @@ +[Unit] +Description=View the web interface if running, on localhost +Requires=webinterface-localhost.socket +After=webinterface-localhost.socket + +[Service] +Type=notify +ExecStart=/lib/systemd/systemd-socket-proxyd 10.11.99.1:80 diff --git a/package/webinterface-localhost/webinterface-localhost.socket b/package/webinterface-localhost/webinterface-localhost.socket new file mode 100644 index 000000000..25c2f8e90 --- /dev/null +++ b/package/webinterface-localhost/webinterface-localhost.socket @@ -0,0 +1,7 @@ +[Socket] +Description=View the web interface if running, on localhost +ListenStream=127.0.0.1:80 +FreeBind=true + +[Install] +WantedBy=sockets.target diff --git a/package/webinterface-onboot/package b/package/webinterface-onboot/package index fc12319fe..0040ffc06 100644 --- a/package/webinterface-onboot/package +++ b/package/webinterface-onboot/package @@ -2,21 +2,22 @@ # Copyright (c) 2021 The Toltec Contributors # SPDX-License-Identifier: MIT -_pkgname='webinterface-onboot' -pkgnames=("$_pkgname") +archs=(rmallos2 rmallos3) +pkgnames=("webinterface-onboot") pkgdesc="Start the web interface without the cable, on boot." -url="https://github.com/rM-self-serve/$_pkgname" -pkgver=1.2.3-1 +url="https://github.com/rM-self-serve/webinterface-onboot" +pkgver=1.2.3-2 timestamp=2023-12-31T11:43:00Z section="utils" maintainer="rM-self-serve <122753594+rM-self-serve@users.noreply.github.com>" license=MIT -conflicts=(ddvk-hacks signature-rm) +conflicts=(signature-rm) +conflicts_rmallos2=(ddvk-hacks) installdepends=(libbfd) source=( "$url"/archive/e184b6a37ccba0ebeacd34faf63c8f4cdfa5c448.zip - "$_pkgname-toltec.service" + "webinterface-onboot-toltec.service" ) sha256sums=( 2e3666b1875f874ef09da2bbd163295b89e9e241f1e59e77349b0e2db716b8ff @@ -24,12 +25,12 @@ sha256sums=( ) package() { - install -D -m 755 -t "$pkgdir/opt/bin" "$srcdir/$_pkgname" - install -D -m 644 "$srcdir/$_pkgname-toltec.service" \ - "$pkgdir/lib/systemd/system/$_pkgname.service" + install -D -m 755 -t "$pkgdir/opt/bin" "$srcdir/$pkgname" + install -D -m 644 "$srcdir/$pkgname-toltec.service" \ + "$pkgdir/lib/systemd/system/$pkgname.service" - touch "$srcdir"/emptyfile - install -D -m 666 -t "$pkgdir"/usr/share/toltec/reenable.d/"$_pkgname" "$srcdir"/emptyfile + mkdir -p "$pkgdir"/opt/share/toltec/reenable.d + touch "$pkgdir"/opt/share/toltec/reenable.d/"$pkgname" } configure() { diff --git a/package/webinterface-upload-button/package b/package/webinterface-upload-button/package index 201285a15..62227cae5 100644 --- a/package/webinterface-upload-button/package +++ b/package/webinterface-upload-button/package @@ -2,11 +2,10 @@ # Copyright (c) 2021 The Toltec Contributors # SPDX-License-Identifier: MIT -_pkgname='webinterface-upload-button' -pkgnames=("$_pkgname") +pkgnames=("webinterface-upload-button") pkgdesc="A simple upload button for the web interface" -url="https://github.com/rM-self-serve/$_pkgname" -pkgver=1.1.1-1 +url="https://github.com/rM-self-serve/webinterface-upload-button" +pkgver=1.1.1-2 timestamp=2023-12-16T15:35:49Z section="utils" maintainer="rM-self-serve <122753594+rM-self-serve@users.noreply.github.com>" @@ -20,11 +19,11 @@ sha256sums=( ) package() { - install -D -m 755 -t "$pkgdir"/opt/bin "$srcdir/$_pkgname" - install -D -m 644 -t "$pkgdir"/usr/share/remarkable/webui/ "$srcdir/$_pkgname.js" + install -D -m 755 -t "$pkgdir"/opt/bin "$srcdir/$pkgname" + install -D -m 644 -t "$pkgdir"/usr/share/remarkable/webui/ "$srcdir/$pkgname.js" - touch "$srcdir"/emptyfile - install -D -m 666 -t "$pkgdir"/usr/share/toltec/reenable.d/"$_pkgname" "$srcdir"/emptyfile + mkdir -p "$pkgdir"/opt/share/toltec/reenable.d + touch "$pkgdir"/opt/share/toltec/reenable.d/"$pkgname" } configure() { diff --git a/package/wireguard/package b/package/wireguard/package index 23665bb19..9a46b62c6 100755 --- a/package/wireguard/package +++ b/package/wireguard/package @@ -1,11 +1,11 @@ #!/usr/bin/env bash # Copyright (c) 2021 The Toltec Contributors # SPDX-License-Identifier: MIT - +archs=(rm1os2 rm2os2) pkgnames=(wireguard) pkgdesc="Fast, modern, secure VPN tunnel" url=https://www.wireguard.com -pkgver=1.0.20210219-4 +pkgver=1.0.20210219-5 timestamp=2021-02-19T14:08Z section=kernel maintainer="Jonah Weissman " diff --git a/package/xochitl/launcherctl-xochitl b/package/xochitl/launcherctl-xochitl new file mode 100755 index 000000000..66c90364b --- /dev/null +++ b/package/xochitl/launcherctl-xochitl @@ -0,0 +1,41 @@ +#!/bin/bash +set -e +case "$1" in + is-active) + systemctl is-active --quiet xochitl.service + ;; + is-enabled) + systemctl is-enabled --quiet xochitl.service + ;; + logs) + if [ $# -eq 2 ] && [[ "$2" == "-f" ]] || [[ "$2" == "--follow" ]]; then + journalctl --follow --all --unit xochitl.service + else + journalctl --no-pager --all --unit xochitl.service + fi + ;; + start | launch) + systemctl start xochitl.service + ;; + stop | close) + systemctl stop xochitl.service + ;; + enable) + systemctl enable xochitl.service + ;; + disable) + systemctl disable xochitl.service + ;; + apps) + echo "xochitl" + ;; + running) + if "$0" is-active; then + echo "xochitl" + fi + ;; + *) + echo "Xochitl does not support this method" + exit 1 + ;; +esac diff --git a/package/xochitl/manual-sync.service b/package/xochitl/manual-sync@.service similarity index 89% rename from package/xochitl/manual-sync.service rename to package/xochitl/manual-sync@.service index 359f84849..386011a02 100644 --- a/package/xochitl/manual-sync.service +++ b/package/xochitl/manual-sync@.service @@ -6,14 +6,14 @@ Description=reMarkable Document Sync without the xochitl.service dependency After=dbus.socket StartLimitIntervalSec=60 StartLimitBurst=4 -Conflicts=sync.service +Conflicts=%i.service [Service] # Do NOT make this dbus, systemd will kill the service when it should be # running otherwise. Type=simple BusName=no.remarkable.sync -ExecStart=/usr/bin/sync --service +ExecStart=/usr/bin/%i --service Restart=on-failure RestartForceExitStatus=SIGHUP SIGINT SIGTERM SIGPIPE diff --git a/package/xochitl/package b/package/xochitl/package index 07fa0a042..c8fb1d132 100644 --- a/package/xochitl/package +++ b/package/xochitl/package @@ -5,7 +5,7 @@ pkgnames=(xochitl) pkgdesc="Read documents and take notes" url=https://remarkable.com -pkgver=0.0.0-17 +pkgver=0.0.0-20 timestamp=2022-11-07T20:19:57Z section="readers" maintainer="Mattéo Delabre " @@ -24,7 +24,8 @@ source=( toltec-after-launcher.conf toltec-wrapper.conf env-readme - manual-sync.service + manual-sync@.service + launcherctl-xochitl ) sha256sums=( SKIP @@ -35,6 +36,7 @@ sha256sums=( SKIP SKIP SKIP + SKIP ) package() { @@ -51,6 +53,7 @@ package() { install -D -m 644 -t "$pkgdir"/opt/etc/draft "$srcdir"/xochitl.draft install -D -m 644 -t "$pkgdir"/opt/etc/draft/icons "$srcdir"/xochitl.png install -D -m 644 -t "$pkgdir"/opt/usr/share/applications "$srcdir"/xochitl.oxide + install -D -T -m 755 "$srcdir"/launcherctl-xochitl "$pkgdir"/opt/share/launcherctl/"$pkgname" install -D -m 644 -t "$pkgdir"/etc/systemd/system/xochitl.service.d \ "$srcdir"/toltec-wrapper.conf @@ -59,19 +62,30 @@ package() { install -D -m 644 -t "$pkgdir"/etc/systemd/system/remarkable-reboot.service.d \ "$srcdir"/toltec-after-launcher.conf install -D -m 644 -t "$pkgdir"/etc/systemd/system \ - "$srcdir"/manual-sync.service + "$srcdir"/manual-sync@.service } configure() { systemctl daemon-reload - # sync.service interferes with launchers - # we use manual-sync.service instead - if [[ "x$(systemctl is-enabled sync.service)" != "xmasked" ]]; then + # sync.service and rm-sync.service interfere with launchers + # we use manual-sync@.service instead + if [ -f /usr/bin/sync ] && ! is-masked sync.service; then systemctl mask sync.service fi - if ! is-active manual-sync.service; then - systemctl enable --now manual-sync.service + + if [ -f /usr/bin/rm-sync ] && ! is-masked rm-sync.service; then + systemctl mask rm-sync.service + fi + + # manual-sync.service has been changed to manual-sync@.service + # Make sure to disable and stop the old version + disable-unit manual-sync.service + + if [ -f /usr/bin/rm-sync ] && ! is-active manual-sync@rm-sync.service; then + systemctl enable --now manual-sync@rm-sync.service + elif [ -f /usr/bin/sync ] && ! is-active manual-sync@sync.service; then + systemctl enable --now manual-sync@sync.service fi if is-enabled xochitl.service && ! is-enabled launcher.service; then @@ -83,14 +97,18 @@ configure() { } preremove() { - disable-unit manual-sync.service + disable-unit manual-sync@rm-sync.service + disable-unit manual-sync@sync.service } postremove() { systemctl daemon-reload - if [[ "x$(systemctl is-enabled sync.service)" == "xmasked" ]]; then - systemctl unmask sync.service 2> /dev/null + if [ -f /usr/bin/sync ] && is-masked sync.service; then + systemctl unmask sync.service + fi + if [ -f /usr/bin/rm-sync ] && is-masked rm-sync.service; then + systemctl unmask rm-sync.service fi if is-enabled xochitl.service && is-enabled launcher.service; then diff --git a/package/xochitl/xochitl b/package/xochitl/xochitl index f16945fe0..4a2eb95f2 100644 --- a/package/xochitl/xochitl +++ b/package/xochitl/xochitl @@ -9,13 +9,22 @@ for file in /opt/etc/xochitl.env.d/*.env; do source "$file" fi done + # If for some reason, sync.service is no longer masked, re-mask it # The package install should have handled this, but something may # have changed it. if [[ "x$(systemctl is-enabled sync.service)" != "xmasked" ]]; then systemctl mask sync.service fi -if ! systemctl is-active --quiet manual-sync.service; then - systemctl enable --now manual-sync.service + +if [[ "x$(systemctl is-enabled rm-sync.service)" != "xmasked" ]]; then + systemctl mask rm-sync.service fi + +if [ -f /usr/bin/rm-sync ] && ! is-active manual-sync@rm-sync.service; then + systemctl enable --now manual-sync@rm-sync.service +elif [ -f /usr/bin/sync ] && ! is-active manual-sync@sync.service; then + systemctl enable --now manual-sync@sync.service +fi + exec -a /usr/bin/xochitl /usr/bin/xochitl "$@" diff --git a/package/zerotier-one/package b/package/zerotier-one/package new file mode 100644 index 000000000..2baabf2ef --- /dev/null +++ b/package/zerotier-one/package @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +# Copyright (c) 2023 The Toltec Contributors +# SPDX-License-Identifier: MIT + +pkgnames=(zerotier zerotier-one zerotier-one-doc zerotier-selftest) +url=https://github.com/zerotier/ZeroTierOne +_upver=1.12.2 +pkgver=${_upver}-1 +timestamp=2023-03-23T17:39:31Z +maintainer="Eeems " +license=BUSL-1.1 +section="utils" +image=base:v3.0 + +source=("https://github.com/zerotier/ZeroTierOne/archive/refs/tags/${_upver}.zip") +sha256sums=(2089fc824c84985610f0bd60186c72e94e2592d8f38259a1c80ea8f696edd16b) + +build() { + sed -i \ + -e 's|/usr/sbin|/opt/bin|' \ + -e 's|/usr/share|/opt/share|' \ + -e 's|/var/lib|/opt/var/lib|' \ + make-linux.mk \ + debian/zerotier-one.service + sed -i \ + -e 's|/var/lib/zerotier-one|/opt/var/lib/zerotier-one|' \ + osdep/OSUtils.cpp + sed -i \ + -e 's|/var/lib/zerotier|/opt/var/lib/zerotier|' \ + doc/zerotier-cli.1 \ + doc/zerotier-cli.1.md \ + doc/zerotier-one.8 \ + doc/zerotier-one.8.md + # Disable SSO as the rust build is broken in rust:v3.0 due to issues with dependencies + export ZT_SSO_SUPPORTED=0 + export ZT_EMBEDDED=1 + export CC=arm-linux-gnueabihf-gcc + export CXX=arm-linux-gnueabihf-g++ + export AR=arm-linux-gnueabihf-ar + export STRIP=arm-linux-gnueabihf-strip + make + make selftest +} + +zerotier() { + pkgdesc="A Smart Ethernet Switch for Earth" + installdepends=(zerotier-one) + # Using 1: to make sure our version always overrides the entware version + pkgver="1:${pkgver}" + package() { + # This is just a wrapper package + true + } +} + +zerotier-one() { + pkgdesc="A Smart Ethernet Switch for Earth" + package() { + cd "$srcdir" + DESTDIR="$pkgdir" make install + rm -r "$pkgdir"/opt/share + install -D -m0644 debian/zerotier-one.service "$pkgdir"/etc/systemd/system/zerotier-one.service + } + configure() { + if ! is-enabled zerotier-one.service; then + how-to-enable zerotier-one.service + fi + if is-active zerotier-one.service; then + systemctl restart zerotier-one.service + fi + } + preremove() { + disable-unit zerotier-one.service + } +} + +zerotier-one-doc() { + installdepends=(man-db) + pkgdesc="Man files for zerotier-one" + package() { + cd "$srcdir" + DESTDIR="$pkgdir" make install + rm -r "$pkgdir"/opt/bin + rm -r "$pkgdir"/opt/var + } +} + +zerotier-selftest() { + pkgdesc="Unit test zerotier to ensure that it works as expected on the system" + package() { + install -D -m 755 -t "$pkgdir"/opt/bin "$srcdir"/zerotier-selftest + } +} diff --git a/requirements.txt b/requirements.txt index a36680a62..45207f4ea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,27 +1,14 @@ -appdirs==1.4.4 -astroid==2.15.4 -black==23.3.0 -certifi==2020.12.5 -chardet==4.0.0 -click==8.1.3 -docker==4.4.1 -idna==2.10 -isort==5.7.0 -Jinja2==2.11.2 -lazy-object-proxy==1.4.3 -MarkupSafe==1.1.1 -mccabe==0.6.1 -mypy==0.790 -mypy-extensions==0.4.3 -pathspec==0.11.1 -pyelftools==0.27 -pylint==2.17.4 -python-dateutil==2.8.1 -regex==2020.11.13 -requests==2.25.1 -six==1.15.0 -toml==0.10.2 -typing-extensions==4.5.0 -urllib3==1.26.2 -websocket-client==0.57.0 -wrapt==1.12.1 +docker==6.1.3 +python-dateutil==2.8.2 +pyelftools==0.29 +black==23.7.0 +pylint==2.17.5 +mypy==1.5.1 +mypy-extensions==1.0.0 +Jinja2==3.1.2 +types-python-dateutil==2.8.19.14 +types-requests==2.31.0.2 +typing-extensions==4.7.1 + +# Pinned due to https://github.com/docker/docker-py/issues/3256 +requests==2.31.0 diff --git a/scripts/bootstrap/bootstrap b/scripts/bootstrap/bootstrap index f72fff16d..997a2e270 100755 --- a/scripts/bootstrap/bootstrap +++ b/scripts/bootstrap/bootstrap @@ -89,7 +89,7 @@ wget-bootstrap() { exit 1 fi - log "Fetching secure wget" + log INFO "Fetching secure wget" # Download and compare to hash mkdir -p "$(dirname "$wget_path")" @@ -174,6 +174,12 @@ main() { # Clean up the partial install if an uncaught error happens trap error-cleanup ERR + if ! check-version "$toltec_branch"; then + if [ $# -eq 0 ] || [[ "$1" != "--force" ]]; then + exit 1 + fi + fi + log "Installing Toltec and Entware" # Create bind mount from user directory to /opt @@ -224,23 +230,12 @@ main() { ln -sf /etc/localtime /opt/etc/localtime fi - # Install base Toltec packages - local additional_packages=(toltec-base) - - [[ ! -d /opt/etc/ssl/certs ]] && additional_packages+=(ca-certificates) - [[ ! -f /opt/bin/wget ]] && additional_packages+=(wget-ssl) - - if [[ ${#additional_packages[@]} -gt 0 ]]; then - opkg install "${additional_packages[@]}" - fi + opkg install toltec-base - if [[ $# -gt 0 ]]; then - opkg install "$@" + if [[ $# -gt 0 ]] && ! /opt/bin/opkg install "$@"; then + log ERROR "The install was still successful, but the requested packages failed to install" fi - # Reinstall toltec-bootstrap to mark its files as managed, - # to install its dependencies, and to set the user’s PATH - opkg install toltec-bootstrap log "After each system upgrade, run 'toltecctl reenable' to re-enable Toltec" } diff --git a/scripts/install-lib b/scripts/install-lib index e5e9f22a4..c151e2c59 100644 --- a/scripts/install-lib +++ b/scripts/install-lib @@ -189,7 +189,7 @@ remove-bind-mount() { # # $1 - Full name of the systemd unit, e.g. "draft.service" unit-exists() { - [ "$(systemctl --quiet list-unit-files "${1}" | grep -c "${1}")" -eq 1 ] + [ "$(systemctl --quiet list-unit-files "${1}" | /bin/grep -c "${1}" 2> /dev/null)" -eq 1 ] } # Stops and disabled a unit diff --git a/scripts/repo_build.py b/scripts/repo_build.py index 4e7d8c69f..9a9b5f1b4 100755 --- a/scripts/repo_build.py +++ b/scripts/repo_build.py @@ -72,3 +72,4 @@ repo.make_index() repo.make_listing() +repo.make_compatibility() diff --git a/scripts/toltec/bash.py b/scripts/toltec/bash.py index b763dd18c..bf74d17bb 100644 --- a/scripts/toltec/bash.py +++ b/scripts/toltec/bash.py @@ -38,6 +38,7 @@ class ScriptError(Exception): "BASH_SUBSHELL", "BASH_VERSINFO", "BASH_VERSION", + "BASH_LOADABLES_PATH", "COLUMNS", "COMP_WORDBREAKS", "DIRSTACK", @@ -132,10 +133,10 @@ def get_declarations(src: str) -> Tuple[Variables, Functions]: while True: token = lexer.get_token() - if token == lexer.eof: + if token == lexer.eof or token is None: break - next_token = lexer.get_token() + next_token = lexer.get_token() or "" if token == "declare" and next_token[0] == "-": lexer.push_token(next_token) @@ -144,8 +145,16 @@ def get_declarations(src: str) -> Tuple[Variables, Functions]: if name not in default_variables: variables[name] = value else: - assert next_token == "(" - assert lexer.get_token() == ")" + if next_token != "(": + raise ScriptError( + f"Unexpected token '{next_token}' on line {lexer.lineno}. Expecting '('." + ) + + _token = lexer.get_token() + if _token != ")": + raise ScriptError( + f"Unexpected token '{_token}' on line {lexer.lineno}. Expecting ')'." + ) start, end = _parse_func(lexer) functions[token] = declarations[start:end] @@ -217,10 +226,13 @@ def _parse_indexed(lexer: shlex.shlex) -> IndexedArray: break assert token == "[" - index = int(lexer.get_token()) + index = int(lexer.get_token() or "") assert lexer.get_token() == "]" assert lexer.get_token() == "=" - value = _parse_string(lexer.get_token()) + string_token = lexer.get_token() or "" + if string_token == "$": + string_token = lexer.get_token() or "" + value = _parse_string(string_token) # Grow the result array so that the index exists if index >= len(result): @@ -247,7 +259,7 @@ def _generate_indexed(array: IndexedArray) -> str: def _parse_assoc(lexer: shlex.shlex) -> AssociativeArray: """Parse an associative Bash array.""" assert lexer.get_token() == "(" - result = {} + result: AssociativeArray = {} while True: token = lexer.get_token() @@ -258,9 +270,13 @@ def _parse_assoc(lexer: shlex.shlex) -> AssociativeArray: assert token == "[" key = lexer.get_token() + assert key is not None assert lexer.get_token() == "]" assert lexer.get_token() == "=" - value = _parse_string(lexer.get_token()) + string_token = lexer.get_token() or "" + if string_token == "$": + string_token = lexer.get_token() or "" + value = _parse_string(string_token) result[key] = value @@ -283,14 +299,14 @@ def _parse_var(lexer: shlex.shlex) -> Tuple[str, Optional[Any]]: """Parse a variable declaration.""" flags_token = lexer.get_token() - if flags_token != "--": + if flags_token != "--" and flags_token is not None: var_flags = set(flags_token[1:]) else: var_flags = set() - var_name = lexer.get_token() + var_name: str = lexer.get_token() or "" var_value: Optional[Any] = None - lookahead = lexer.get_token() + lookahead = lexer.get_token() or "" if lookahead == "=": if "a" in var_flags: @@ -298,7 +314,10 @@ def _parse_var(lexer: shlex.shlex) -> Tuple[str, Optional[Any]]: elif "A" in var_flags: var_value = _parse_assoc(lexer) else: - var_value = _parse_string(lexer.get_token()) + string_token = lexer.get_token() or "" + if string_token == "$": + string_token = lexer.get_token() or "" + var_value = _parse_string(string_token) else: lexer.push_token(lookahead) diff --git a/scripts/toltec/builder.py b/scripts/toltec/builder.py index ee14b0e29..249162793 100644 --- a/scripts/toltec/builder.py +++ b/scripts/toltec/builder.py @@ -48,10 +48,13 @@ class BuildContextAdapter(logging.LoggerAdapter): def process( self, msg: str, kwargs: MutableMapping[str, Any] ) -> Tuple[str, MutableMapping[str, Any]]: + if self.extra is None: + return msg, kwargs + prefix = "" if "recipe" in self.extra: - prefix += self.extra["recipe"] + prefix += str(self.extra["recipe"]) if "arch" in self.extra: prefix += f" [{self.extra['arch']}]" @@ -657,7 +660,7 @@ def _archive(self, package: Package, pkg_dir: str) -> None: def _print_logs( self, logs: bash.LogGenerator, - function_name: str = None, + function_name: Optional[str] = None, max_lines_on_fail: int = 50, ) -> None: """ diff --git a/scripts/toltec/repo.py b/scripts/toltec/repo.py index af9c1ad28..62f9b3273 100644 --- a/scripts/toltec/repo.py +++ b/scripts/toltec/repo.py @@ -9,6 +9,7 @@ from enum import Enum, auto import logging import os +import shutil import textwrap from typing import Dict, Iterable, List, Optional, Set import requests @@ -55,10 +56,10 @@ def __init__(self, recipe_dir: str, repo_dir: str) -> None: self.repo_dir = repo_dir self.generic_recipes = {} - for name in os.listdir(self.recipe_dir): - if name[0] != ".": - self.generic_recipes[name] = GenericRecipe.from_file( - os.path.join(self.recipe_dir, name) + for entry in os.scandir(self.recipe_dir): + if entry.is_dir(): + self.generic_recipes[entry.name] = GenericRecipe.from_file( + entry.path ) def fetch_packages(self, remote: Optional[str]) -> GroupedPackages: @@ -266,3 +267,10 @@ def make_listing(self) -> None: # pylint: disable-next=unspecified-encoding with open(listing_path, "w") as listing_file: listing_file.write(template.render(sections=sections)) + + def make_compatibility(self) -> None: + """Generate the OS compatibility information file.""" + logger.info("Generating compatibility info") + compat_source = os.path.join(self.recipe_dir, "Compatibility") + compat_dest = self.repo_dir + shutil.copy2(compat_source, compat_dest)