<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 16 Oct 2020 at 18:50, Ed Tanous <<a href="mailto:ed@tanous.net">ed@tanous.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wed, Oct 14, 2020 at 11:49 AM Anton Kachalov <<a href="mailto:rnouse@google.com" target="_blank">rnouse@google.com</a>> wrote:<br>
><br>
> With moving from root-only environment to unprivileged users' space, we need to ensure a smooth transition. To achieve that we need a mechanism for one-shot per-package scripts that would take care of migration. That's not only about groups & owners, but a general approach.<br>
<br>
Are there other use cases that necessitate a general approach?  I'm<br>
not against it, but owners and groups seems unique in the regard that<br>
the migration has to run as root.  Most (all?) other migrations don't<br>
seem to, or haven't in the past, and therefore can be run as a<br>
pre-init, or as part of the service itself.  If the service itself<br>
does the migration, the startup dependencies are a lot easier to track<br>
as a maintainer, and running your migrations in a compiled language<br>
likely has a positive effect on boot time, which has been a problem in<br>
the past (still is depending on who you ask).<br></blockquote><div><br></div><div>For instance, the bmcweb has some internal logic for migration of some files. The problem with "in-service" compiled code is that the service will be run with least privileges and could be sandboxed, thus, wouldn't be able to modify filesystem.</div><div><br></div><div>The migration scripts have to be part of the corresponding package, thus, it will be easy to track & maintain.</div><div><br></div><div>The one-time run scripts wouldn't make too much overhead if they run once.</div><div><br></div><div>Pre-init like StartExecPre= option in the service file isn't a good choice because it will run every time and really increase the boot time.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
It should be noted, several apps have done simple migrations of config<br>
file formats in the past, so there's some precedent for it, just not<br>
in a generalist solution.<br>
<br>
>  It's similar to firstboot, but has a different purpose.<br>
><br>
> I'm going to prototype a robust / naive solution to start a service before everything else in the system with a condition (non-empty /etc/migration.d) and iterate through all files. Each script has to run at list with "set -e" to bail out on failures. If the script succeeded -- it will be removed.<br>
<br>
The script itself will be removed?  Presumably that means you're<br>
executing the script out of non-volatile?  That seems like a security<br>
gap in that an attacker could inject migration scripts that did<br>
anything, and have the system run them for them.  Maybe just keeping<br>
some kind of external log of "these scripts have completed" or,<br>
preferably, enforcing that migration scripts are idempotent would be<br>
better, and would reduce the possibility of a bad actor getting<br>
permanent execution privileges if they somehow overwrote the scripts?<br></blockquote><div><br></div><div>Basically, we can have a SHA-sum with a list of approved scripts to run. Such lists have to be placed on the read-only part. The way how to mark the succeeded scripts may vary. We can have scripts available on the same read-only partition and touch files somewhere under /var/lib for the succeeded ones. As well as make the scripts re-entrant in case of losing state files.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
><br>
> The tricky part is: what if the script fails? Keep it, ignore the failure and proceed with others and then boot the system? Or proceed other scripts as well and then enter some "failure state"?<br>
<br>
Assuming you can have migrations that are interlinked, have to be run<br>
in order, and sometimes can fail, maybe the "best" thing to do is to<br>
simply stop on the failing one, and try to boot the system as well as<br>
it's able to in the degraded state.  This would mean that flakey<br>
scripts would be rerun on the next boot, and hopefully succeed, and<br>
consistently failing scripts could be replaced on a subsequent<br>
firmware update with more robust versions, and rerun.<br></blockquote><div><br></div><div>Are there any read-to-use API / scripts to make the system boot in degraded mode? Otherwise, we can just add this functionality later.</div></div></div>