OSTree update /usr/local/* RW folders fail


I’m trying to add some custom python libraries into the host system using the torizoncore-builder OSTree filesystem customization, like it is defined in the documentation: TorizonCore Builder Tool “build” command | Toradex Developer Center.
Before that I checked the setup by putting the files manually via scp on the board and putting the files into /usr/local/bin and /usr/local/lib pathes, then modified the /etc/environment to add the /usr/local/lib path into the PYTHONPATH and with these changes all was fine and worked flawlessly.
When I define the customization and put the libraries file tree like this:


- changes/

disk file tree

… packages dirs …
The files are not put into the place. From the documentation I know that /usr/ and /usr/lib are the read-only paths and it is clear that it should be ignored, but /usr/local/ is not a read-only otherwise I wouldn’t be able to put the files there.
For me it is non important where to put that python code, although it would be natural to use /usr/local/lib path for that. Is there a way to bypass the read-only constraint here? Is there any full list of directories that will be ignored in the filesystem customization?

Thank you!

Hi, I’m the Toradex AI Assistant. I’m in early beta, and I would appreciate your feedback.
The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


When using TorizonCore Builder for OSTree filesystem customization, it’s crucial to understand how the read-only and read-write partitions are managed. As you’ve observed, TorizonCore mounts the root filesystem as read-only to improve security and system reliability, with certain exceptions like /etc and /var for specific reasons.

For adding custom Python libraries or any modifications outside the standard read-write directories, there are a couple of approaches you can consider:

  1. OverlayFS: This is a union filesystem that allows you to virtually “overlay” additional files on top of the existing filesystem without modifying the original files. This can be particularly useful for adding files to read-only parts of the filesystem like /usr/local. You can create an overlay that includes your custom libraries and configure it to be applied at boot time.

  2. Custom OSTree Compose: Another approach is to create a custom OSTree commit that includes your changes. This involves setting up an OSTree repository, adding your changes to the filesystem tree, and then committing those changes to create a new OSTree commit. This new commit can then be deployed to your devices. This method requires a deeper understanding of OSTree but offers a more integrated solution for customizing the filesystem.

Regarding the list of directories ignored in filesystem customization, it’s not about specific directories being ignored by the customization process itself but rather about how the OSTree and the filesystem are structured in TorizonCore. The root filesystem is mounted as read-only, and modifications are generally intended to be made in directories designed for runtime changes (/etc, /var) or through mechanisms like OverlayFS or custom OSTree commits that respect the read-only nature of the system.

For your specific case of adding Python libraries, consider placing them in a directory within /var or using one of the above methods to overlay or include them in the filesystem. This ensures that your customizations are preserved across updates and do not interfere with the system’s integrity.

Remember, direct modifications to the read-only parts of the filesystem are not recommended or supported due to the potential for system instability and the risk of changes being lost during updates.

Best regards,
Toradex AI Assistant

Please, also check if these links can help you solve your problem:

Torizon OS Technical Overview | Toradex Developer Center.

Hey @ollamh,

TorizonCore Builder uses OSTree for it’s updating.There are a few special cases are treated differently.

/var and /etc are persistent coniguration/user data between updates.

and from our docs:

  • /etc: when OSTree creates a deployment, it performs a 3-way merge using the old default configuration, the active system’s /etc, and the new default configuration. In the final filesystem tree for a deployment, /etc is a regular writable directory that can be used to store system configuration.
  • /var: this directory is not touched by OSTree, and can be used to store logs, databases and any other data consumed or generated by applications.
  • /home: this directory is also not touched by OSTree and can be used to store any user-related files. It is actually a link to /var/rootdirs/home.

Also its important to note the isolate command from torizoncore-builder will get changes made to the /etc file on the target board, not from the /usr/etc. /usr/etc has modifications from previous deployments. The difference between /etc and /usr/etc is the “captured difference”


Hi @eric.tx , thanks for the explanation, but my question is slightly different.

I need to put some python libs into the system by using OSTree changes. Hope that this is the correct way to install any Python dependency into the host system, let me know if it is not. Therefore those changes are currently the part of the OSTree commit, because I’m using the customization / filesystem section of the tcbuild.yaml file. Due to the fact that this python code may change, I need to have it as the part of OSTree changes and I can’t put it under /var or /home folders.
My question was - could /usr/local/(bin|lib) be the right place to put the files into? I can defined such filetree and it is not ignored by OSTree, but the data is not moved from /usr/usr/local/lib into /usr/local/lib. I assume because anything that starts with /usr/ is considered as an attempt to write into read-only filesystem and it is ignored by OSTree at the deployment stage, right?
So, my current “workaround” is to store code into /etc/usr/local/(lib|bin) and modify $PATH and $PYTHONPATH env variables. It works, but it isn’t perfect…


Hey @ollamh,

You’ll notice with /usr/local this is actually a symlink to the /var/usrlocal. And this is why you are able to put files there. And is handled in the way that is expected with OSTree.

torizon@verdin-imx8mp-07011921:~$ ls -l /usr/local
lrwxrwxrwx 3 root root 15 Apr 25 08:09 /usr/local -> ../var/usrlocal

Torizon OS has a docker runtime included in the OS. Are you familiar? It would be typical to see your required libraries/programs built within containers.


1 Like

Hey @eric.tx , thanks, I know about docker runtime, but I need to have those libs to be precisely on the host OS as I mentioned previously. I used /etc/ path at the end. Thanks!