Difference between revisions of "Pmbootstrap development guide"

From postmarketOS
Jump to: navigation, search
(remove git hook, that was only related to the aports (and doesn't exist in this form anymore anyway, if someone was still using this, please reach out in the issues))
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Code ==
+
=== Installation code (<code>pmb.install.*</code>) ===
=== pmb.helpers.run ===
+
Whenever you change the installation process, also adjust the recovery zip installer (which performs a good part of the installation procedure directly on the Android device with a shell script).
Use <code>pmb.helpers.run.root()</code> and <code>pmb.helpers.run.user()</code> instead of <code>subprocess</code> because these write to the log file.
+
 
 +
=== What is this <code>args</code> variable used everywhere? ===
 +
See the big comment at the top of [https://gitlab.com/postmarketOS/pmbootstrap/blob/master/pmb/helpers/args.py <code>pmb/helpers/args.py</code>].
 +
 
 +
=== Executing shell commands ===
 +
Use one of the following functions instead of Python's built in <code>subprocess</code>:
 +
 
 +
* [https://gitlab.com/postmarketOS/pmbootstrap/blob/master/pmb/helpers/run.py <code>pmb.helpers.run.user()</code>]
 +
* [https://gitlab.com/postmarketOS/pmbootstrap/blob/master/pmb/helpers/run.py <code>pmb.helpers.run.root()</code>]
 +
* [https://gitlab.com/postmarketOS/pmbootstrap/blob/master/pmb/chroot/user.py <code>pmb.chroot.user()</code>]
 +
* [https://gitlab.com/postmarketOS/pmbootstrap/blob/master/pmb/chroot/root.py <code>pmb.chroot.root()</code>]
 +
 
 +
These functions call [https://gitlab.com/postmarketOS/pmbootstrap/blob/master/pmb/helpers/run_core.py <code>pmb.helpers.run_core.core()</code>] internally to write to the log file (that you can read with <code>pmbootstrap log</code>) and timeout when there is no output. A lot of function parameters are passed through to <code>core()</code> as well, see its docstring for a detailed description of what these parameters do.
  
==== Shell commands ====
+
==== Writing to files ====
 
{{note|See also: {{github|1316}} Properly escape commands in pmb.chroot.user()}}
 
{{note|See also: {{github|1316}} Properly escape commands in pmb.chroot.user()}}
 
The passed commands gets interpreted as single command, and not executed in a shell. This means something like the following '''will not work''':
 
The passed commands gets interpreted as single command, and not executed in a shell. This means something like the following '''will not work''':
Line 27: Line 39:
 
pmb.chroot.root(args, ["mv", "/tmp/somefile", "/etc/somefile"])
 
pmb.chroot.root(args, ["mv", "/tmp/somefile", "/etc/somefile"])
 
</syntaxhighlight>
 
</syntaxhighlight>
 
=== pmb.install ===
 
Whenever you change the installation process, also adjust the recovery zip installer (which performs a good part of the installation procedure directly on the Android device with a shell script).
 
  
 
== See also ==
 
== See also ==
 
* [[Testsuite]]
 
* [[Testsuite]]
 +
 +
[[Category:Guide]]

Latest revision as of 04:23, 17 December 2018

Installation code (pmb.install.*)

Whenever you change the installation process, also adjust the recovery zip installer (which performs a good part of the installation procedure directly on the Android device with a shell script).

What is this args variable used everywhere?

See the big comment at the top of pmb/helpers/args.py.

Executing shell commands

Use one of the following functions instead of Python's built in subprocess:

These functions call pmb.helpers.run_core.core() internally to write to the log file (that you can read with pmbootstrap log) and timeout when there is no output. A lot of function parameters are passed through to core() as well, see its docstring for a detailed description of what these parameters do.

Writing to files

See also: #1316 Properly escape commands in pmb.chroot.user()

The passed commands gets interpreted as single command, and not executed in a shell. This means something like the following will not work:

pmb.chroot.root(args, ["echo", "test", ">", "/tmp/test"])

Instead, if you need shell functionality in the call, you can wrap the call with sh -c. Here's one example with the parameters correctly escaped (you don't need to do that for the strings in this example, but if you pass variables then they should be escaped properly):

shell_cmd = "echo " + shutil.quote("test") + " > " + shutil.quote("/tmp/test")
pmb.chroot.root(args, ["sh", "-c", shell_cmd])

Another technique (especially if you need to run many commands in the shell at once) is writing all commands down into a temporary file and executing it with the shell, see for example pmb/chroot/initfs.py.

Writing files to the chroot

The users in the chroots (root and pmos) have different user IDs than the user of the host system. Therefore we can't just write a file to anywhere in the chroot. But we can write to /tmp and move the file afterwards:

with open("tmp/somefile", "w") as handle:
    handle.write("It works")
pmb.chroot.root(args, ["mv", "/tmp/somefile", "/etc/somefile"])

See also