-
Notifications
You must be signed in to change notification settings - Fork 512
docs: document application command-chain #5599
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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 | ||||||||||||||||||||||
| always the application executable. | ||||||||||||||||||||||
|
Comment on lines
+6
to
+9
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
As in different
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried to clear it up a little:
Suggested change
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?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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 | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
| ``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
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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" "$@" | ||||||||||||||||||||||
There was a problem hiding this comment.
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: