From 0df19729f0f460b89593ac00e9f48dd28c4c9122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Sun, 26 Sep 2021 23:58:33 +0200 Subject: [PATCH 01/11] Create rmfakecloud-proxy package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR provides a new package intended to ease the setup of rmfakecloud on a device. [rmfakecloud](https://github.com/ddvk/rmfakecloud) is an alternative Xochitl sync server developed by ddvk that anyone can self-host. With this package, connecting to an rmfakecloud server only takes a few steps: * `opkg install rmfakecloud-proxy` * `rmfakecloudctl set-upstream https://...` (define the server to use) * `rmfakecloudctl enable` One can then run `rmfakecloudctl disable` (or uninstall the package) to revert back to the default reMarkable servers. Technical details ----------------- This package reuses most of its logic from the rmfakecloud-proxy installer , but makes it more integrated with Toltec. The following steps happen when enabling rmfakecloud-proxy: * A local certificate authority and a self-signed certificate are generated for the reMarkable cloud domain names (stored in `/opt/var/rmfakecloud-proxy`). * The `rmfakecloud-proxy` service is enabled. This is a proxy server listening on `127.0.42.10` which forwards any requests it receives to the server selected by running `rmfakecloudctl set-upstream`. * Entries are written to the `/etc/hosts` file to direct requests to the reMarkable cloud to the `rmfakecloud-proxy` server. Additionally, if one is already connected to the reMarkable cloud in Xochitl when enabling rmfakecloud-proxy (or connected to rmfakecloud when disabling it), the script takes care of disconnecting them and marking their files as unsynced. This prevents Xochitl from believing that the files have disappeared from the server and therefore deleting them. The “enabled” state survives package upgrades and system upgrades. This state is stored as a file in `/opt/etc/rmfakecloud-proxy/enabled` which exists if and only if the proxy is enabled. Test plan --------- Please make a backup of your files (in `~/.local/share/remarkable/xochitl`) before testing this. To test this PR, you’ll need access to an rmfakecloud instance. I can give temporary access to my instance if needed. The following scenarios should be tested: * Installing and enabling rmfakecloud-proxy while previously being connected to the reMarkable cloud: no files should be lost and they should sync to the server. * Installing and enabling rmfakecloud-proxy while not being connected to the rM cloud: same result as before. * After enabling rmfakecloud-proxy, switching to a different rmfakecloud server with `rmfakecloud set-upstream`: no files should be lost. * Upgrading the system while being connected to rmfakecloud: the rmfakecloud connection should be re-enabled after running `toltecctl reenable`. * Running `rmfakecloudctl disable` should remove entries from the `/etc/hosts` file, uninstall the self-signing CA and disconnect the user. No files should be lost. * Removing the rmfakecloud-proxy package should disable rmfakecloud. --- package/rmfakecloud-proxy/package | 85 +++++ .../rmfakecloud-proxy-wrapper | 24 ++ .../rmfakecloud-proxy.service | 12 + package/rmfakecloud-proxy/rmfakecloudctl | 319 ++++++++++++++++++ 4 files changed, 440 insertions(+) create mode 100644 package/rmfakecloud-proxy/package create mode 100644 package/rmfakecloud-proxy/rmfakecloud-proxy-wrapper create mode 100644 package/rmfakecloud-proxy/rmfakecloud-proxy.service create mode 100644 package/rmfakecloud-proxy/rmfakecloudctl diff --git a/package/rmfakecloud-proxy/package b/package/rmfakecloud-proxy/package new file mode 100644 index 000000000..7312f2ae5 --- /dev/null +++ b/package/rmfakecloud-proxy/package @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# Copyright (c) 2021 The Toltec Contributors +# SPDX-License-Identifier: MIT + +pkgnames=(rmfakecloud-proxy) +pkgdesc="Connect Xochitl to a rmfakecloud server" +_url=https://github.com/ddvk/rmfakecloud-proxy +url="$_url" +_upver=0.0.3 +pkgver="$_upver-1" +timestamp=2021-09-26T20:38:44Z +section="utils" +maintainer="Mattéo Delabre " +license=MIT +installdepends=(procps-ng-pgrep) + +image=golang:v2.2 +source=( + "https://github.com/ddvk/rmfakecloud-proxy/archive/v$_upver.zip" + rmfakecloudctl + rmfakecloud-proxy-wrapper + rmfakecloud-proxy.service +) +sha256sums=( + eaa3fdcce250e23f368a4c9ddcfb99ff178decf31b2a7f84501dfc6fdb2e6d8f + SKIP + SKIP + SKIP +) + +build() { + eval "$(go env)" + cat > version.go < /dev/null; then + systemctl stop xochitl + was_active=1 + fi + + if pgrep xochitl > /dev/null; then + killall xochitl + sleep 1s + fi + + if pgrep xochitl > /dev/null; then + killall -9 xochitl + sleep 1s + fi + + # Mark all files as not synced + grep sync "$xochitl_data_dir"/*.metadata -l \ + | xargs sed -i 's/synced\": true/synced\": false/' + + # Disconnect from cloud + sed -i '/^devicetoken=/d' "$xochitl_conf_path" + sed -i '/^usertoken=/d' "$xochitl_conf_path" + + # Re-enable Xochitl service if it was running + if [[ -n $was_active ]]; then + systemctl start xochitl + fi +} + +# Check if the proxy has been enabled +# +# Exit code: +# +# 0 - If the proxy is enabled +# Other - If the proxy is disabled +is-enabled() { + [[ -f $conf_dir/enabled ]] +} + +mark-enabled() { + mkdir -p "$conf_dir" + touch "$conf_dir/enabled" +} + +mark-disabled() { + rm -f "$conf_dir/enabled" +} + +# Read the currently configured upstream server +# +# Output: Name of the configured server +# Exit code: +# +# 0 - If a server is configured +# 1 - If no server is configured +get-upstream() { + local upstream + + if ! upstream="$(cat "$conf_dir/upstream" 2> /dev/null)"; then + return 1 + fi + + if [[ -z $upstream ]]; then + return 1 + fi + + echo "$upstream" +} + +# Define the upstream server, overwriting any previously configured value +# +# Arguments: +# +# $1 - Name of the server +set-upstream() { + mkdir -p "$conf_dir" + echo "$1" > "$conf_dir/upstream" +} + +# Generate a local certificate authority, add it to the system trust, +# and create a self-signed proxy certificate +install-certificates() { + mkdir -p "$data_dir" "$local_cert_dir" + + if [[ ! -f $data_dir/rmfakecloud-ca.key ]] \ + || [[ ! -f $data_dir/rmfakecloud-ca.crt ]]; then + openssl genrsa -out "$data_dir/rmfakecloud-ca.key" 2048 + openssl req -new -sha256 -x509 \ + -key "$data_dir/rmfakecloud-ca.key" \ + -out "$data_dir/rmfakecloud-ca.crt" \ + -days 3650 -subj /CN=rmfakecloud-ca + rm -f "$data_dir/rmfakecloud-proxy.key" + fi + + if ! cmp -s {"$data_dir","$local_cert_dir"}/rmfakecloud-ca.crt; then + cp -f "$data_dir/rmfakecloud-ca.crt" "$local_cert_dir" + update-ca-certificates --fresh + fi + + if [[ ! -f $data_dir/rmfakecloud-proxy.key ]]; then + openssl genrsa -out "$data_dir/rmfakecloud-proxy.key" 2048 + rm -f "$data_dir/rmfakecloud-proxy.pubkey" + fi + + if [[ ! -f $data_dir/rmfakecloud-proxy.pubkey ]]; then + openssl rsa -in "$data_dir/rmfakecloud-proxy.key" -pubout \ + -out "$data_dir/rmfakecloud-proxy.pubkey" + rm -f "$data_dir/rmfakecloud-proxy.crt" + fi + + if [[ ! -f $data_dir/rmfakecloud-proxy.crt ]]; then + local csr + csr="$(mktemp)" + + cat >> "$csr" << CSR +[ req ] +default_bits = 2048 +default_keyfile = proxy.key +encrypt_key = no +default_md = sha256 +prompt = no +utf8 = yes +distinguished_name = dn +req_extensions = ext +x509_extensions = caext +[ dn ] +C = AA +ST = QQ +L = JJ +O = the culture +CN = *.appspot.com +[ ext ] +subjectAltName=@san +basicConstraints=CA:FALSE +subjectKeyIdentifier = hash +[ caext ] +subjectAltName=@san +[ san ] +DNS.1 = *.appspot.com +DNS.2 = my.remarkable.com +DNS.3 = internal.cloud.remarkable.com +DNS.4 = ping.remarkable.com +DNS.5 = *.remarkable.com +CSR + + openssl req -new -config "$csr" \ + -key "$data_dir/rmfakecloud-proxy.key" \ + -out "$data_dir/rmfakecloud-proxy.csr" + openssl x509 -req -in "$data_dir/rmfakecloud-proxy.csr" \ + -out "$data_dir/rmfakecloud-proxy.crt" \ + -CA "$data_dir/rmfakecloud-ca.crt" \ + -CAkey "$data_dir/rmfakecloud-ca.key" -CAcreateserial \ + -days 3650 -extfile "$csr" -extensions caext + rm -f "$data_dir/rmfakecloud-proxy.csr" + fi + + if [[ ! -f $data_dir/rmfakecloud-proxy.bundle.crt ]]; then + cat "$data_dir/rmfakecloud-proxy.crt" "$data_dir/rmfakecloud-ca.crt" \ + > "$data_dir/rmfakecloud-proxy.bundle.crt" + fi +} + +# Untrust the local certificate authority +uninstall-certificates() { + if [[ -f "$local_cert_dir/rmfakecloud-ca.crt" ]]; then + rm "$local_cert_dir/rmfakecloud-ca.crt" + update-ca-certificates --fresh + fi +} + +# Add entries in the static host file to redirect cloud requests to the proxy +install-hosts() { + uninstall-hosts + cat <> "$hosts_path" +$proxy_listen hwr-production-dot-remarkable-production.appspot.com +$proxy_listen service-manager-production-dot-remarkable-production.appspot.com +$proxy_listen local.appspot.com +$proxy_listen my.remarkable.com +$proxy_listen internal.cloud.remarkable.com +$proxy_listen ping.remarkable.com +EOF +} + +# Remove all static host entries redirecting the cloud to the proxy +uninstall-hosts() { + sed -i '/ hwr-production-dot-remarkable-production.appspot.com$/d' "$hosts_path" + sed -i '/ service-manager-production-dot-remarkable-production.appspot.com$/d' "$hosts_path" + sed -i '/ local.appspot.com$/d' "$hosts_path" + sed -i '/ my.remarkable.com$/d' "$hosts_path" + sed -i '/ internal.cloud.remarkable.com$/d' "$hosts_path" + sed -i '/ ping.remarkable.com$/d' "$hosts_path" +} + +help() { + echo "Usage: $(basename "$0") COMMAND +Manage rmfakecloud-proxy. Available commands: + + help Show this help message. + enable Enable rmfakecloud-proxy. + set-upstream Define the rmfakecloud server. + disable Disable rmfakecloud-proxy." +} + +if [[ $0 = "${BASH_SOURCE[0]}" ]]; then + if [[ $# -eq 0 ]]; then + help + exit 1 + fi + + action="$1" + shift + + case $action in + enable) + if is-enabled; then + echo "rmfakecloud-proxy is already enabled." + else + disconnect-cloud + install-certificates + install-hosts + mark-enabled + systemctl enable rmfakecloud-proxy + systemctl restart rmfakecloud-proxy + echo "rmfakecloud-proxy is now enabled." + fi + ;; + + disable) + if is-enabled; then + disconnect-cloud + mark-disabled + systemctl disable --now rmfakecloud-proxy + uninstall-hosts + uninstall-certificates + echo "rmfakecloud-proxy is now disabled." + else + echo "rmfakecloud-proxy is already disabled." + fi + ;; + + set-upstream) + if (($# < 1)); then + echo "Missing server name argument" + exit 1 + fi + + if [[ $(get-upstream) == "$1" ]]; then + echo "Server already set to '$1'." + else + disconnect-cloud + set-upstream "$1" + echo "Upstream server configuration changed successfully." + + if is-enabled; then + systemctl restart rmfakecloud-proxy + else + cat << MSG +Run the following command to enable rmfakecloud-proxy: + +$ rmfakecloudctl enable +MSG + fi + fi + ;; + + help | -h | --help) + help + ;; + + *) + echo -e "Error: Invalid command '$action'\n" + help + exit 1 + ;; + esac +fi From 2ffa84e1314e6d9bee363986fa4505a0b0163de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Wed, 29 Sep 2021 19:49:58 +0200 Subject: [PATCH 02/11] Fix formatting --- package/rmfakecloud-proxy/package | 4 ++-- package/rmfakecloud-proxy/rmfakecloudctl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package/rmfakecloud-proxy/package b/package/rmfakecloud-proxy/package index 7312f2ae5..8259681e7 100644 --- a/package/rmfakecloud-proxy/package +++ b/package/rmfakecloud-proxy/package @@ -30,7 +30,7 @@ sha256sums=( build() { eval "$(go env)" - cat > version.go < version.go << GO package main const Version = "rmfakecloud-proxy ${_upver%-*} ($GOOS-$GOARCH) $GOVERSION\n$_url" GO @@ -63,7 +63,7 @@ configure() { fi if ! is-enabled; then - cat <> "$hosts_path" + cat << EOF >> "$hosts_path" $proxy_listen hwr-production-dot-remarkable-production.appspot.com $proxy_listen service-manager-production-dot-remarkable-production.appspot.com $proxy_listen local.appspot.com From 7fbea684059a0852e43f1d29285595b418e48c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Thu, 30 Sep 2021 11:05:43 +0200 Subject: [PATCH 03/11] Add more dependencies to the service --- package/rmfakecloud-proxy/rmfakecloud-proxy.service | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package/rmfakecloud-proxy/rmfakecloud-proxy.service b/package/rmfakecloud-proxy/rmfakecloud-proxy.service index 5ad2fd264..62e3c24fc 100644 --- a/package/rmfakecloud-proxy/rmfakecloud-proxy.service +++ b/package/rmfakecloud-proxy/rmfakecloud-proxy.service @@ -1,7 +1,8 @@ [Unit] Description=rmfakecloud reverse proxy Documentation=https://github.com/ddvk/rmfakecloud-proxy -After=home.mount +After=home.mount network.target +Before=xochitl.service launcher.service [Service] Environment=HOME=/home/root From 64541de15d229a4ba5f1f411424312a6ca642156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Thu, 30 Sep 2021 11:39:26 +0200 Subject: [PATCH 04/11] Fix unbound variable in rmfakecloudctl --- package/rmfakecloud-proxy/rmfakecloudctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/rmfakecloud-proxy/rmfakecloudctl b/package/rmfakecloud-proxy/rmfakecloudctl index 4a07bdb01..05c809d0c 100644 --- a/package/rmfakecloud-proxy/rmfakecloudctl +++ b/package/rmfakecloud-proxy/rmfakecloudctl @@ -39,7 +39,7 @@ disconnect-cloud() { fi # Make sure Xochitl is not running - local was_active + local was_active= if systemctl --quiet is-active xochitl.service 2> /dev/null; then systemctl stop xochitl From 0f1d68a04e28c69883867901d44037063714e7a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Thu, 30 Sep 2021 11:39:52 +0200 Subject: [PATCH 05/11] set-upstream: Show enable prompt in all cases if disabled --- package/rmfakecloud-proxy/rmfakecloudctl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/package/rmfakecloud-proxy/rmfakecloudctl b/package/rmfakecloud-proxy/rmfakecloudctl index 05c809d0c..5050d18fa 100644 --- a/package/rmfakecloud-proxy/rmfakecloudctl +++ b/package/rmfakecloud-proxy/rmfakecloudctl @@ -296,13 +296,15 @@ if [[ $0 = "${BASH_SOURCE[0]}" ]]; then if is-enabled; then systemctl restart rmfakecloud-proxy - else - cat << MSG + fi + fi + + if ! is-enabled; then + cat << MSG Run the following command to enable rmfakecloud-proxy: $ rmfakecloudctl enable MSG - fi fi ;; From 3cb7cf06d412b339820af1c68b53660ed14785ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Thu, 30 Sep 2021 11:40:49 +0200 Subject: [PATCH 06/11] Replace wrapper with yaml config file --- package/rmfakecloud-proxy/package | 2 -- .../rmfakecloud-proxy-wrapper | 24 ------------------- .../rmfakecloud-proxy.service | 4 +++- package/rmfakecloud-proxy/rmfakecloudctl | 18 +++++++++++--- 4 files changed, 18 insertions(+), 30 deletions(-) delete mode 100644 package/rmfakecloud-proxy/rmfakecloud-proxy-wrapper diff --git a/package/rmfakecloud-proxy/package b/package/rmfakecloud-proxy/package index 8259681e7..92c1263ea 100644 --- a/package/rmfakecloud-proxy/package +++ b/package/rmfakecloud-proxy/package @@ -18,7 +18,6 @@ image=golang:v2.2 source=( "https://github.com/ddvk/rmfakecloud-proxy/archive/v$_upver.zip" rmfakecloudctl - rmfakecloud-proxy-wrapper rmfakecloud-proxy.service ) sha256sums=( @@ -41,7 +40,6 @@ GO package() { install -D -m 755 -t "$pkgdir"/opt/bin "$srcdir"/dist/rmfakecloud-proxy install -D -m 755 -t "$pkgdir"/opt/bin "$srcdir"/rmfakecloudctl - install -D -m 755 -t "$pkgdir"/opt/bin "$srcdir"/rmfakecloud-proxy-wrapper install -D -m 644 -t "$pkgdir"/lib/systemd/system "$srcdir"/rmfakecloud-proxy.service } diff --git a/package/rmfakecloud-proxy/rmfakecloud-proxy-wrapper b/package/rmfakecloud-proxy/rmfakecloud-proxy-wrapper deleted file mode 100644 index c93e4e3f5..000000000 --- a/package/rmfakecloud-proxy/rmfakecloud-proxy-wrapper +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2021 The Toltec Contributors -# SPDX-License-Identifier: MIT - -# shellcheck source=rmfakecloudctl -source /opt/bin/rmfakecloudctl - -if ! is-enabled; then - echo "rmfakecloud-proxy is not enabled." - echo "Run 'rmfakecloudctl enable' to enable it." - exit -fi - -if ! upstream="$(get-upstream)"; then - echo "rmfakecloud-proxy server is not configured." - echo "Use 'rmfakecloudctl set-upstream' to configure it." - exit -fi - -exec /opt/bin/rmfakecloud-proxy \ - -addr "$proxy_listen:443" \ - -cert "$data_dir/rmfakecloud-proxy.bundle.crt" \ - -key "$data_dir/rmfakecloud-proxy.key" \ - "$upstream" diff --git a/package/rmfakecloud-proxy/rmfakecloud-proxy.service b/package/rmfakecloud-proxy/rmfakecloud-proxy.service index 62e3c24fc..3440aaa8b 100644 --- a/package/rmfakecloud-proxy/rmfakecloud-proxy.service +++ b/package/rmfakecloud-proxy/rmfakecloud-proxy.service @@ -3,10 +3,12 @@ Description=rmfakecloud reverse proxy Documentation=https://github.com/ddvk/rmfakecloud-proxy After=home.mount network.target Before=xochitl.service launcher.service +ConditionPathExists=/opt/etc/rmfakecloud-proxy/enabled +ConditionPathExists=/opt/etc/rmfakecloud-proxy/config [Service] Environment=HOME=/home/root -ExecStart=/opt/bin/rmfakecloud-proxy-wrapper +ExecStart=/opt/bin/rmfakecloud-proxy -c /opt/etc/rmfakecloud-proxy/config Restart=on-failure [Install] diff --git a/package/rmfakecloud-proxy/rmfakecloudctl b/package/rmfakecloud-proxy/rmfakecloudctl index 5050d18fa..f3e334892 100644 --- a/package/rmfakecloud-proxy/rmfakecloudctl +++ b/package/rmfakecloud-proxy/rmfakecloudctl @@ -98,8 +98,15 @@ mark-disabled() { # 1 - If no server is configured get-upstream() { local upstream - - if ! upstream="$(cat "$conf_dir/upstream" 2> /dev/null)"; then + # shellcheck disable=SC2016 + local awk_program=' + /^upstream:/{ + sep = index($0, ":"); + print gensub(/^[ \t]+|[ \t]+$/, "", "g", substr($0, sep + 1)); + } + ' + + if ! upstream="$(awk "$awk_program" "$conf_dir/config" 2> /dev/null)"; then return 1 fi @@ -117,7 +124,12 @@ get-upstream() { # $1 - Name of the server set-upstream() { mkdir -p "$conf_dir" - echo "$1" > "$conf_dir/upstream" + cat > "$conf_dir/config" << YAML +cert: $data_dir/rmfakecloud-proxy.bundle.crt +key: $data_dir/rmfakecloud-proxy.key +upstream: $1 +addr: $proxy_listen:443 +YAML } # Generate a local certificate authority, add it to the system trust, From b6b68a59a4ee4f26bafcc9f969f4a0661d67c6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Thu, 30 Sep 2021 11:44:06 +0200 Subject: [PATCH 07/11] Remove leftover checksum entry --- package/rmfakecloud-proxy/package | 1 - 1 file changed, 1 deletion(-) diff --git a/package/rmfakecloud-proxy/package b/package/rmfakecloud-proxy/package index 92c1263ea..c09e29f7b 100644 --- a/package/rmfakecloud-proxy/package +++ b/package/rmfakecloud-proxy/package @@ -24,7 +24,6 @@ sha256sums=( eaa3fdcce250e23f368a4c9ddcfb99ff178decf31b2a7f84501dfc6fdb2e6d8f SKIP SKIP - SKIP ) build() { From 0fe270cc0def4020ae4e05f99b723897c6369916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Wed, 6 Oct 2021 01:19:06 +0200 Subject: [PATCH 08/11] Remove pgrep dependency & properly wait for process termination --- package/rmfakecloud-proxy/package | 1 - package/rmfakecloud-proxy/rmfakecloudctl | 40 +++++++++++++++++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/package/rmfakecloud-proxy/package b/package/rmfakecloud-proxy/package index c09e29f7b..2e2704711 100644 --- a/package/rmfakecloud-proxy/package +++ b/package/rmfakecloud-proxy/package @@ -12,7 +12,6 @@ timestamp=2021-09-26T20:38:44Z section="utils" maintainer="Mattéo Delabre " license=MIT -installdepends=(procps-ng-pgrep) image=golang:v2.2 source=( diff --git a/package/rmfakecloud-proxy/rmfakecloudctl b/package/rmfakecloud-proxy/rmfakecloudctl index f3e334892..bd292e0b0 100644 --- a/package/rmfakecloud-proxy/rmfakecloudctl +++ b/package/rmfakecloud-proxy/rmfakecloudctl @@ -26,6 +26,24 @@ xochitl_conf_path=/home/root/.config/remarkable/xochitl.conf # Path to Xochitl data xochitl_data_dir=/home/root/.local/share/remarkable/xochitl +# Find a process by its name (like pgrep) +# +# Arguments: +# +# $1 - Exact comm name to match +# +# Output: PID of any matching process +# Exit code: 0 if a process was found, 1 otherwise +get-process() { + for procdir in /proc/*; do + if [[ -f $procdir/comm ]] && [[ $1 == "$(cat "$procdir/comm")" ]]; then + basename "$procdir" + return 0 + fi + done + return 1 +} + # Disconnect Xochitl from the cloud # # This is a necessary step when switching cloud servers to prevent the client @@ -46,14 +64,22 @@ disconnect-cloud() { was_active=1 fi - if pgrep xochitl > /dev/null; then - killall xochitl - sleep 1s - fi + local xochitl_pid= + + if xochitl_pid="$(get-process xochitl)"; then + kill "$xochitl_pid" + echo "Waiting for Xochitl to stop" + local xochitl_wait_count=0 - if pgrep xochitl > /dev/null; then - killall -9 xochitl - sleep 1s + while kill -0 "$xochitl_pid" 2> /dev/null; do + sleep 1 + xochitl_wait_count=$((xochitl_wait_count++)) + + if ((xochitl_wait_count > 5)); then + echo "Force killing Xochitl" + kill -9 "$xochitl_pid" + fi + done fi # Mark all files as not synced From b656ee456a804e5e4226be7d788bc0afa68595a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Wed, 6 Oct 2021 01:25:46 +0200 Subject: [PATCH 09/11] Force using /usr/bin/xargs --- package/rmfakecloud-proxy/rmfakecloudctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/rmfakecloud-proxy/rmfakecloudctl b/package/rmfakecloud-proxy/rmfakecloudctl index bd292e0b0..5a438c9f9 100644 --- a/package/rmfakecloud-proxy/rmfakecloudctl +++ b/package/rmfakecloud-proxy/rmfakecloudctl @@ -84,7 +84,7 @@ disconnect-cloud() { # Mark all files as not synced grep sync "$xochitl_data_dir"/*.metadata -l \ - | xargs sed -i 's/synced\": true/synced\": false/' + | /usr/bin/xargs sed -i 's/synced\": true/synced\": false/' # Disconnect from cloud sed -i '/^devicetoken=/d' "$xochitl_conf_path" From 4096e93187e3f31dc3527c1bef6cdc86eaa76eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Wed, 6 Oct 2021 11:58:50 +0200 Subject: [PATCH 10/11] Add back dependency on pgrep + add findutils dep --- package/rmfakecloud-proxy/package | 1 + package/rmfakecloud-proxy/rmfakecloudctl | 22 ++-------------------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/package/rmfakecloud-proxy/package b/package/rmfakecloud-proxy/package index 2e2704711..9bdfbda4d 100644 --- a/package/rmfakecloud-proxy/package +++ b/package/rmfakecloud-proxy/package @@ -12,6 +12,7 @@ timestamp=2021-09-26T20:38:44Z section="utils" maintainer="Mattéo Delabre " license=MIT +installdepends=(procps-ng-pgrep findutils) image=golang:v2.2 source=( diff --git a/package/rmfakecloud-proxy/rmfakecloudctl b/package/rmfakecloud-proxy/rmfakecloudctl index 5a438c9f9..721c2308b 100644 --- a/package/rmfakecloud-proxy/rmfakecloudctl +++ b/package/rmfakecloud-proxy/rmfakecloudctl @@ -26,24 +26,6 @@ xochitl_conf_path=/home/root/.config/remarkable/xochitl.conf # Path to Xochitl data xochitl_data_dir=/home/root/.local/share/remarkable/xochitl -# Find a process by its name (like pgrep) -# -# Arguments: -# -# $1 - Exact comm name to match -# -# Output: PID of any matching process -# Exit code: 0 if a process was found, 1 otherwise -get-process() { - for procdir in /proc/*; do - if [[ -f $procdir/comm ]] && [[ $1 == "$(cat "$procdir/comm")" ]]; then - basename "$procdir" - return 0 - fi - done - return 1 -} - # Disconnect Xochitl from the cloud # # This is a necessary step when switching cloud servers to prevent the client @@ -66,7 +48,7 @@ disconnect-cloud() { local xochitl_pid= - if xochitl_pid="$(get-process xochitl)"; then + if xochitl_pid="$(pgrep --exact --oldest xochitl)"; then kill "$xochitl_pid" echo "Waiting for Xochitl to stop" local xochitl_wait_count=0 @@ -84,7 +66,7 @@ disconnect-cloud() { # Mark all files as not synced grep sync "$xochitl_data_dir"/*.metadata -l \ - | /usr/bin/xargs sed -i 's/synced\": true/synced\": false/' + | xargs sed -i 's/synced\": true/synced\": false/' # Disconnect from cloud sed -i '/^devicetoken=/d' "$xochitl_conf_path" From be4ea86d4f13b264885d7860e6d8c34005f4b9c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Fri, 26 Nov 2021 19:02:03 -0500 Subject: [PATCH 11/11] Rollback failed or interrupted installs --- package/rmfakecloud-proxy/rmfakecloudctl | 53 ++++++++++++++++-------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/package/rmfakecloud-proxy/rmfakecloudctl b/package/rmfakecloud-proxy/rmfakecloudctl index 721c2308b..852427c2a 100644 --- a/package/rmfakecloud-proxy/rmfakecloudctl +++ b/package/rmfakecloud-proxy/rmfakecloudctl @@ -223,8 +223,10 @@ CSR fi } -# Untrust the local certificate authority +# Erase and untrust the local certificate authority uninstall-certificates() { + rm -f "$data_dir"/* + if [[ -f "$local_cert_dir/rmfakecloud-ca.crt" ]]; then rm "$local_cert_dir/rmfakecloud-ca.crt" update-ca-certificates --fresh @@ -254,6 +256,36 @@ uninstall-hosts() { sed -i '/ ping.remarkable.com$/d' "$hosts_path" } +# Try to make a full install of rmfakecloud-proxy +install() { + trap install-failed EXIT + disconnect-cloud + install-certificates + install-hosts + mark-enabled + systemctl enable rmfakecloud-proxy + systemctl restart rmfakecloud-proxy + trap EXIT +} + +install-failed() { + echo "Install interrupted, trying to clean up" + uninstall +} + +# Disable and cleanup rmfakecloud-proxy +uninstall() { + # Temporarily disable exit-on-error so as to clean up as much as possible + set +e + disconnect-cloud + mark-disabled + systemctl disable --now rmfakecloud-proxy + rm -f "$conf_dir/config" + uninstall-hosts + uninstall-certificates + set -e +} + help() { echo "Usage: $(basename "$0") COMMAND Manage rmfakecloud-proxy. Available commands: @@ -278,27 +310,14 @@ if [[ $0 = "${BASH_SOURCE[0]}" ]]; then if is-enabled; then echo "rmfakecloud-proxy is already enabled." else - disconnect-cloud - install-certificates - install-hosts - mark-enabled - systemctl enable rmfakecloud-proxy - systemctl restart rmfakecloud-proxy + install echo "rmfakecloud-proxy is now enabled." fi ;; disable) - if is-enabled; then - disconnect-cloud - mark-disabled - systemctl disable --now rmfakecloud-proxy - uninstall-hosts - uninstall-certificates - echo "rmfakecloud-proxy is now disabled." - else - echo "rmfakecloud-proxy is already disabled." - fi + uninstall + echo "rmfakecloud-proxy is now disabled." ;; set-upstream)