Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions docs/explanation/command-chain.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
.. _explanation-command-chain:

Command Chain
=============

Command chain is a mechanism for running small pieces of code before the main
application executable. The chain uses ``exec`` to transition the process from
the current element of the chain to the next. The last element of the chain is
Comment on lines +7 to +8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of:

Suggested change
application executable. The chain uses ``exec`` to transition the process from
the current element of the chain to the next. The last element of the chain is
application executable. The chain uses the ``exec`` command to shift from
the current command to the next. The last element of the chain is

always the application executable.
Comment on lines +6 to +9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Command chain is a mechanism for running small pieces of code before the main
application executable. The chain uses ``exec`` to transition the process from
the current element of the chain to the next. The last element of the chain is
always the application executable.
A command chain is a mechanism for running small pieces of code before the main
application executable. The chain uses ``exec`` to transition the process from
the current element of the chain to the next. The last element of the chain is
always the application executable.

It's important to use articles to distinguish between a concept/category, and actual objects in the software that users interact with.


Uses
----

Command chain may be used to modify process environment, perform initialization
steps or anything else that makes sense in a given situation. Command chain
elements are usually reusable across applications. Command chain elements are
Comment on lines +15 to +16
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Command chain elements are usually reusable across applications.

As in different app entries in the same snap or different snaps? The "usually" in this sentence and the next sentence are throwing me off. Is this referring to scripts that get re-used like desktop-launch or alsa-launch?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to convey that you can use the same command chain element across many snaps and many apps as they are kind of "middleware". Let me know how to re-phrase that in the text.

also usually stackable, so an application can use several tailored command
chain elements to perform unrelated functions.
Comment on lines +14 to +18
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to clear it up a little:

Suggested change
Command chain may be used to modify process environment, perform initialization
steps or anything else that makes sense in a given situation. Command chain
elements are usually reusable across applications. Command chain elements are
also usually stackable, so an application can use several tailored command
chain elements to perform unrelated functions.
A command chains is used to modify the process environment, perform initialization
steps, or any other situation where an ordered sequence of commands is needed.
Chained commands are usually reusable between apps in a part. The commands are
also usually stackable, so an application can use several tailored commands to
perform unrelated functions.

I said "apps in a part", but that might be too narrow for what @zyga is saying.

I'm not sure what we mean by "usually stackable". When are they not stackable? Isn't that an inherent quality of the concept?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The are stackable in the sense that you can take a command chain that, say, handles fontconfig cache, then another one that prepares your XDG configuration, then another one to generate locale data based on what the user is doing and each of those programs is entirely unrelated to each other, and can be used across apps and snaps.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I follow the metaphor. Is it different than being modular?


.. code-block:: yaml
:caption: snapcraft.yaml

apps:
hello:
command: bin/hello
command-chain:
- bin/foo
- bin/bar
Comment on lines +27 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- bin/foo
- bin/bar
- bin/foo
- bin/bar

Not every system in our tooling plays nice with same-indentation collections.


Here, when the application ``hello`` is started, snapd performs a sequence of
initialization steps executed by distinct programs. Execution starts by running
``/bin/snap``. Execution then continues by ``exec`` to a specific copy of
``snap-confine``, followed by another ``exec`` to ``snap-exec``. In the absence
of command-chain elements, ``snap-exec`` executes the application binary. In
the presence of command chain, the first element of the chain, ``bin/foo``
executes instead.

Protocol
--------

Every element of the chain is responsible for executing the next chain by
calling ``exec`` (without forking the process). Here both ``bin/foo`` and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
calling ``exec`` (without forking the process). Here both ``bin/foo`` and
calling ``exec`` (without forking the process). Continuing with the previous example, both ``bin/foo`` and

``bin/bar`` would follow the same protocol, ultimately executing ``bin/hello``.
The next element of the chain is passed through the process argument vector.

In the example above, ``snap-exec`` would call ``exec bin/foo bin/bar
bin/hello`` with ``bin/foo`` as the program path and program name and ``bin/bar
bin/hello`` as arguments. This protocol continues until the application entry
point is reached.
Comment on lines +42 to +49
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Food for thought: this could also be visualised as a series of nodes in ASCII. It would reinforce the meaning.


Example
-------

Both ``bin/foo`` and ``bin/bar`` can be written as simple shell scripts or
comprehensive, compiled programs. A shell version might look like this. Notice
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
comprehensive, compiled programs. A shell version might look like this. Notice
compiled programs. A shell version might look like this. Notice

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would put the "Notice..." sentence after the code block, so the reader has the chance to look at the code and think about it before we isolate part of it.

that the argument ``$0`` is the name of the program (command chain element),
while remaining arguments, here represented as ``"$@"`` are executed to
implement the protocol.

.. code-block:: shell
:caption: bin/foo

#!/bin/sh
echo "command chain element $0"
exec "$@"


The line ``exec "$@"`` can be written more verbosely to illustrate how chain
elements link together via ``exec``.

.. code-block:: shell
:caption: bin/foo

#!/bin/sh
echo "command chain element $0"
chain_next="$1"
shift
exec "$chain_next" "$@"
1 change: 1 addition & 0 deletions docs/explanation/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ and their implementation.
remote-build
/common/craft-parts/explanation/filesets
classic-confinement
command-chain