tiny-pilot / tinypilot

Use your Raspberry Pi as a browser-based KVM.
https://tinypilotkvm.com
MIT License
2.95k stars 245 forks source link

Create a dedicated script for removing TinyPilot auto-generated changes #1710

Closed mtlynch closed 6 months ago

mtlynch commented 7 months ago

When TinyPilot modifies config files owned by other services, we sometimes add custom markers that allow us to back out our changes later:

We're about to add a third incarnation of this code on the website repo:

We should refactor this logic into a script whose only job is to remove the TinyPilot-generated section. We can use this reusable script for removing lines and markers rather than duplicating the logic in multiple places.

Example

$ cat example.conf
foo=bar

# --- AUTOGENERATED BY TINYPILOT - START ---
tinypilot_timing=7
hdmi_output=3
# --- AUTOGENERATED BY TINYPILOT - END ---

baz=baa

$ /opt/tinypilot/scripts/remove-tinypilot-lines < example.conf
foo=bar

baz=baa
jotaen4tinypilot commented 6 months ago

I’m not sure we can easily consolidate the instance in unset-static-ip: the code contains additional logic to account for the --interface flag, so it only removes marker sections that match the given network interface, and disregards any other marker section. For example, if multiple static IP configurations for different network interfaces had been added to dhcpcd.conf, then they are each wrapped into their own markers. You can then do e.g. unset-static-ip --interface eth0, to only remove the one particular marker section for the eth0 interface, while leaving all other marker sections untouched.

A potential solution that would come to my mind is to provide some sort of filter functionality in an otherwise generic remove-tinypilot-lines script, to check whether a marker section is eligible for dropping. However, I’m worried that this would complicate things instead of simplifying them, partly because it might be cumbersome to express such filter clauses with bash APIs.

We originally introduced the static IP CLI scripts a year ago. I don’t know whether we actually make use of the multi-interface functionality anywhere in practice right now, and whether it’s therefore safe or not to drop it:

I think we could generally consider to establish an internal convention around these marker sections. My intuitive take is (was) that there should only be one marker section per file, and we must always be able to re-generate the section in its entirety. That at least would be the main benefit that I’d see in using the marker section approach over something more sophisticated. Otherwise, we have to do (conditional) parsing work to inspect the contents of the file, and that is actually what the marker section approach tries to avoid.

jotaen4tinypilot commented 6 months ago

That being said, my question is how we’d proceed from here best? E.g.,

jotaen4tinypilot commented 6 months ago

(WIP branch, including bats tests; unfortunately, I didn’t notice this problem earlier / right away.)

mtlynch commented 6 months ago

I think we can just drop the --interface flag from unset-static-ip. In other words, unset-static-ip removes all TinyPilot-assigned static IPs from all interfaces.

We should make it error out if the user passes an --interface flag so that we don't silently break old behavior if anyone has scripts relying on this (unlikely, but possible).

For this to break a use-case, we'd need to have a user go through a flow like this, correct?

  1. Assign a static IP to eth0
  2. Assign a static IP to wlan0
  3. Remove a static IP from eth0 only

I think the number of users who go through a flow like that is vanishingly small, probably zero.

I don't recall anyone ever requesting support for this. I think we just added it because "why not?" and we didn't think through the maintenance burden.

jotaen4tinypilot commented 6 months ago

I think we can just drop the --interface flag from unset-static-ip. In other words, unset-static-ip removes all TinyPilot-assigned static IPs from all interfaces.

Okay cool, that simplifies things a lot.

For this to break a use-case, we'd need to have a user go through a flow like this, correct?

Correct. In this case two things could happen when they call the unset-static-ip script:

I’d do this now:

  1. Remove --interface flag from unset-static-ip API as discussed, to make unset-static-ip on par with change-hostname.
  2. Introduce unified remove-tinypilot-lines script
  3. Introduce bats tests
  4. Switch unset-static-ip and change-hostname to delegate to remove-tinypilot-lines.
jotaen4tinypilot commented 6 months ago

One addendum, just for the records: set-static-ip invokes unset-static-ip. So users will effectively only be able to configure one interface at a time, because trying to set a second one would clear any previously set configuration.

So regarding the scenario above:

  1. Assign a static IP to eth0
  2. Assign a static IP to wlan0 ← This clears the assignment from step 1, only leaving wlan0
mtlynch commented 6 months ago

So users will effectively only be able to configure one interface at a time, because trying to set a second one would clear any previously set configuration.

Ah, I hadn't considered that. Still, I think it's probably a rare scenario to need static IP for both WiFi and Ethernet. If we get requests for that, it shouldn't be too hard for us to revisit the feature and figure out a way to support it later.