Skip to content

Commit 48c362c

Browse files
committed
chapter/app-interact: Restructure Application Interaction chapter
This commit restructures the Application Interaction chapter according to OpenEdu methodology. Signed-off-by: Iacobai Cosmin-Andrei <[email protected]>
1 parent b7a2314 commit 48c362c

File tree

253 files changed

+4092
-1120
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

253 files changed

+4092
-1120
lines changed

chapters/app-interact/Makefile

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# The script expect the source .svg files to be named as $TARGET-$i.svg, where $i is the frame number.
2+
TARGETS = synchronization interruption
3+
RVMD = reveal-md
4+
MDPP = markdown-pp
5+
FFMPEG = ffmpeg
6+
7+
SLIDES ?= slides.mdpp
8+
SLIDES_OUT ?= slides.md
9+
SITE ?= _site
10+
OPEN ?= xdg-open
11+
12+
.PHONY: all html clean videos
13+
14+
all: videos html
15+
16+
html: $(SITE)
17+
18+
$(SITE): $(SLIDES)
19+
$(MDPP) $< -o $(SLIDES_OUT)
20+
$(RVMD) $(SLIDES_OUT) --static $@
21+
22+
videos:
23+
for TARGET in $(TARGETS); do \
24+
TARGET_DIR=$$(find -name $$TARGET -type d | grep media); \
25+
MEDIA_DIR=$$(dirname $$TARGET_DIR); \
26+
$(FFMPEG) -framerate 0.5 -f image2 -y \
27+
-i "$$TARGET_DIR/$$TARGET-%d.svg" -vf format=yuv420p $$MEDIA_DIR/$$TARGET-generated.gif; \
28+
done
29+
30+
open: $(SITE)
31+
$(OPEN) $</index.html
32+
33+
clean:
34+
-for i in $$(find -name "*-generated.gif"); do rm -f $$i; done
35+
-rm -f *~
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# D-Bus - Battery level
2+
3+
Use D-Bus to find out the computer's battery level.
4+
There is the `org.freedesktop.UPower` interface on the system bus that can provide this information.
5+
<!-- markdownlint-disable MD101 -->
6+
The method you need to call is `org.freedesktop.DBus.Properties.Get` from the `/org/freedesktop/UPower/devices/DisplayDevice` object.
7+
<!-- markdownlint-enable MD101 -->
8+
9+
This method needs 2 arguments: an interface name and a property name.
10+
<!-- markdownlint-disable MD101 -->
11+
Those should be `org.freedesktop.UPower.Device` and `Percentage` respectively.
12+
<!-- markdownlint-enable MD101 -->
13+
14+
Then input all of the above into a `gdbus` call, which, if everything is correct, should output the battery percentage level as a number between 0 and 100.
15+
16+
Note: if you are running on a desktop computer or inside a virtual machine, you will get the value `0.0`, because those systems don't have a battery.
17+
18+
If you're having difficulties solving this exercise, go through [this](../../../reading/dbus.md) reading material.
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
#!/bin/bash
2+
# SPDX-License-Identifier: BSD-3-Clause
23

34
gdbus call --system --dest org.freedesktop.UPower --object-path /org/freedesktop/UPower/devices/DisplayDevice --method org.freedesktop.DBus.Properties.Get "org.freedesktop.UPower.Device" "Percentage"

content/chapters/app-interact/lab/support/dbus/send_notification.sh chapters/app-interact/dbus/drills/tasks/dbus/support/send_notification.sh

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/bin/bash
2+
# SPDX-License-Identifier: BSD-3-Clause
23

34
gdbus call \
45
--session --dest org.freedesktop.Notifications \

content/chapters/app-interact/lab/support/dbus/send_notification_strace.sh chapters/app-interact/dbus/drills/tasks/dbus/support/send_notification_strace.sh

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/bin/bash
2+
# SPDX-License-Identifier: BSD-3-Clause
23

34
strace -s 1000 -f -e trace=socket,connect,sendmsg,recvmsg \
45
gdbus call \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Calling D-Bus Methods
2+
3+
The application behind `org.freedesktop.Notifications` is responsible with desktop notifications (the small bubbles of text that appear at the top of the screen when some event happens).
4+
When an application wants to send a notification it needs to connect to D-Bus and call the `Notify` method from the `org.freedesktop.Notifications` interface.
5+
6+
In this example, we want to call the `Notify` method ourselves.
7+
To do this, we must first understand the signature of this method:
8+
9+
`Notify (String arg_0, UInt32 arg_1, String arg_2, String arg_3, String arg_4, Array of [String] arg_5, Dict of {String, Variant} arg_6, Int32 arg_7) ↦ (UInt32 arg_8)`
10+
11+
This doesn't tell us much, but we can find more documentation [here](https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html#basic-design), since `freedesktop` is an open standard.
12+
13+
We'll set the arguments to the following (for our simple case, most of them will be unused):
14+
15+
- `app_name`: `""`
16+
17+
- `replaces_id`: `0`
18+
19+
- `app_icon`: `""`
20+
21+
- `summary`: `"This is the title"`
22+
23+
- `body`: `"This is the content"`
24+
25+
- `actions`: `[]`
26+
27+
- `hints`: `{}`
28+
29+
- `expire_timeout`: `-1`
30+
31+
Now the question is how to actually call the method.
32+
Normally, we would have to write an application that connects to D-Bus and executes the call.
33+
But for demonstrative purposes there are easier ways.
34+
35+
One way is directly from d-feet.
36+
If we double-click on the `Notify` method in the right-side pane of d-feet, a window will open that allows us to call the method with any arguments that we want:
37+
38+
![dfeet-execute-dialog](../media/dfeet_execute.png)
39+
40+
Then we click the `Execute` button and the notification will appear:
41+
42+
![dfeet-execute-](../media/dfeet_execute.gif)
43+
44+
Another way is from the command-line. There's the `gdbus` tool that can do this:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# D-Bus Inspection with D-Feet
2+
3+
In order to better understand these concepts, we'll use a graphical tool (`D-Feet`) to inspect all the available D-Bus objects on our system.
4+
5+
Run D-Feet and select `Session Bus` from the top button:
6+
7+
![dfeet-session-bus](../media/dfeet_session_bus.png)
8+
9+
On the left panel, we can see all the processes connected to D-Bus with their associated `connection names`.
10+
Scroll down and find `org.freedesktop.Notifications`.
11+
On the right side, expand `/org/freedesktop/Notifications` and then expand the `org.freedesktop.Notifications` interface.
12+
The window should look like this:
13+
14+
![dfeet-notifications](../media/dfeet_notifications.png)
15+
16+
Some observations:
17+
18+
- The bus communication happens over a Unix socket, with the path `/run/user/1000/bus`.
19+
20+
- `org.freedesktop.Notifications` on the left panel is the `connection name`.
21+
22+
- The process that has connected with this name is `/usr/bin/gjs /usr/share/gnome-shell/org.gnome.Shell.Notifications` and has the pid of `4373`.
23+
24+
- This process exposes one object: `/org/freedesktop/Notifications`.
25+
Note that the object name is the same as the connection name, where the dots have been replaced with slashes.
26+
This is not a requirement, as the objects exposed by a process can have any name.
27+
28+
<!-- markdownlint-disable MD101 -->
29+
- The object has 4 interfaces: `org.freedesktop.DBus.Introspectable`, `org.freedesktop.DBus.Peer`, `org.freedesktop.DBus.Properties` and `org.freedesktop.Notifications`.
30+
Note that the last one (`org.freedesktop.Notifications`) is the same as the connection name, but this again is just a coincidence, not a requirement.
31+
<!-- markdownlint-enable MD101 -->
32+
33+
- The interface `org.freedesktop.Notifications` has some methods that can be called, such as `Notify`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# D-Bus usage in Python
2+
3+
Use the `dbus` python bindings to get the computer's battery level using a python script.
4+
You can start from the documentation [here](https://dbus.freedesktop.org/doc/dbus-python/tutorial.html#).
5+
You need to read the sections `Connecting to the Bus`, `Proxy objects`, and `Interfaces and methods`.
6+
7+
There's also a skeleton you can use in `chapters/app-interact/arena/support/dbus/get_battery_level.py`.
8+
9+
In summary, your script will start by connecting to the `System Bus`.
10+
Then you'll use the `get_object` method to obtain a proxy object.
11+
On this proxy object, you can actually do the method call as explained [here](https://dbus.freedesktop.org/doc/dbus-python/tutorial.html#interfaces-and-methods):
12+
13+
```text
14+
To call a method, call the method of the same name on the proxy object, passing in the interface name via the dbus_interface keyword argument
15+
```
16+
17+
So, if you want to call the method `this.is.an.interface.method` with the arguments `A` and `B` you can do it like this:
18+
19+
```python
20+
result = proxy.method(A, B, dbus_interface = "this.is.an.interface")
21+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Firefox
2+
3+
Let's do the following experiment:
4+
5+
- Open the Firefox browser
6+
7+
- From a terminal run `firefox www.google.com`
8+
9+
![firefox-url-open](../media/firefox_url_open.gif)
10+
11+
Notice that the URL we passed in the command-line was opened in the existing Firefox window as a new tab.
12+
Even though we started a separate Firefox process, which should have created a separate new window, this didn't actually happen.
13+
Instead, the process that we started from the command-line exited immediately and the site was opened in the already running Firefox instance.
14+
15+
Without any precise knowledge about Firefox internals, we can guess that something like this happened:
16+
17+
- The newly started Firefox process detected that another instance of Firefox is already running
18+
19+
- The newly started Firefox process sent a message to the existing running process, requesting it to open a URL in a new tab
20+
21+
Since we're talking about message passing between 2 processes, there's a chance that maybe D-Bus was involved.
22+
Let's check: we'll use a tool called `dbus-monitor` that will print all messages passed through D-Bus.
23+
24+
```console
25+
student@os:~$ dbus-monitor
26+
```
27+
28+
Then, in another terminal, we'll run `firefox www.google.com` again.
29+
30+
Going back to the `dbus-monitor` output, we find the following:
31+
32+
```console
33+
...
34+
method call time=1655809062.813923 sender=:1.757 -> destination=org.mozilla.firefox.ZGVmYXVsdC1yZWxlYXNl serial=2 path=/org/mozilla/firefox/Remote; interface=org.mozilla.firefox; member=OpenURL
35+
array of bytes [
36+
02 00 00 00 1a 00 00 00 2f 00 00 00 2f 68 6f 6d 65 2f 61 64 72 69 61 6e
37+
73 00 2f 6f 70 74 2f 66 69 72 65 66 6f 78 2f 66 69 72 65 66 6f 78 00 77
38+
77 77 2e 67 6f 6f 67 6c 65 2e 63 6f 6d 00
39+
]
40+
```
41+
42+
There was a D-Bus call to `org.mozilla.firefox.ZGVmYXVsdC1yZWxlYXNl`, on the object `/org/mozilla/firefox/Remote`, method `OpenURL` from the `org.mozilla.firefox` interface.
43+
Indeed, we see that this object exists in d-feet as well:
44+
45+
![dfeet-firefox](../media/dfeet_firefox.png)
46+
47+
We can try to call the `OpenURL` method ourselves, directly from d-feet.
48+
The method has only one argument of the type `Array of [Byte]`.
49+
Although there's no documentation for it, we can use the same byte array that we saw in `dbus-monitor`:
50+
51+
```console
52+
array of bytes [
53+
02 00 00 00 1a 00 00 00 2f 00 00 00 2f 68 6f 6d 65 2f 61 64 72 69 61 6e
54+
73 00 2f 6f 70 74 2f 66 69 72 65 66 6f 78 2f 66 69 72 65 66 6f 78 00 77
55+
77 77 2e 67 6f 6f 67 6c 65 2e 63 6f 6d 00
56+
]
57+
```
58+
59+
(Note that `77 77 77 2e 67 6f 6f 67 6c 65 2e 63 6f 6d` at the end is the string `www.google.com`, so that's another confirmation that we're on the right track).
60+
61+
![dfeet-url-open](../media/dfeet_url_open.gif)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Inspecting the Low-level Communication
2+
3+
Let's run `gdbus` under `strace` to see what's happening behind the scenes.
4+
Run the script in `support/dbus/send_notification_strace.sh`:
5+
6+
```console
7+
strace: Process 61888 attached
8+
[pid 61887] socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 5
9+
[pid 61887] connect(5, {sa_family=AF_UNIX, sun_path="/run/user/1000/bus"}, 110) = 0
10+
[pid 61887] sendmsg(5, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\0", iov_len=1}], msg_iovlen=1,
11+
msg_control=[{cmsg_len=28, cmsg_level=SOL_SOCKET, cmsg_type=SCM_CREDENTIALS, cmsg_data={pid=61887,
12+
uid=1000, gid=1000}}],
13+
msg_controllen=32, msg_flags=0}, MSG_NOSIGNAL) = 1
14+
strace: Process 61889 attached
15+
16+
[...]
17+
18+
[pid 61889] sendmsg(5, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="l\1\0\1T\0\0\0\3\0\0\0\237\0\0\0\1
19+
\1o\0\36\0\0\0/org/freedesktop/Notifications\0\0\2\1s\0\35\0\0\0org.freedesktop.Notifications\0\0\0\6\1s\0\35
20+
\0\0\0org.freedesktop.Notifications\0\0\0\10\1g\0\rsusssasa{sv}i\0\0\0\0\0\0\3\1s\0\6\0\0\0Notify\0\0\0\0\0\0
21+
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\21\0\0\0This is the title\0\0\0\23\0\0\0This is the content\0\0\0\0\0\0\0\0\0
22+
\0\0\0\0\377\377\377\377", iov_len=260}], msg_iovlen=1, msg_controllen=0,
23+
msg_flags=0}, MSG_NOSIGNAL) = 260
24+
[pid 61889] recvmsg(5, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="l\2\1\1\4\0\0\0\312\0\0\0.\0\0\0", iov_len=16}],
25+
msg_iovlen=1, msg_controllen=0, msg_flags=MSG_CMSG_CLOEXEC}, MSG_CMSG_CLOEXEC) = 16
26+
[pid 61889] recvmsg(5, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\6\1s\0\6\0\0\0:1.497\0\0\10\1g\0\1u\0\0\5\1u\0
27+
\3\0\0\0\7\1s\0\5\0\0\0:1.49\0\0\0\36\0\0\0", iov_len=52}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_CMSG_CLOEXEC}, MSG_CMSG_CLOEXEC) = 52
28+
(uint32 30,)
29+
[pid 61889] +++ exited with 0 +++
30+
[pid 61888] +++ exited with 0 +++
31+
+++ exited with 0 +++
32+
```
33+
34+
We see a Unix socket being created and a connection made to `/run/user/1000/bus`, as expected.
35+
Then a series of messages are exchanged on the socket, which are part of the D-Bus protocol.
36+
On a closer look, we can even identify some strings from our notification, like `This is the title` or `This is the content`:
37+
38+
```console
39+
[pid 61889] sendmsg(5, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="l\1\0\1T\0\0\0\3\0\0\0\237\0\0\0\1
40+
\1o\0\36\0\0\0/org/freedesktop/Notifications\0\0\2\1s\0\35\0\0\0org.freedesktop.Notifications\0\0\0\6\1s\0\35
41+
\0\0\0org.freedesktop.Notifications\0\0\0\10\1g\0\rsusssasa{sv}i\0\0\0\0\0\0\3\1s\0\6\0\0\0Notify\0\0\0\0\0\0
42+
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\21\0\0\0This is the title\0\0\0\23\0\0\0This is the content\0\0\0\0\0\0\0\0\0
43+
\0\0\0\0\377\377\377\377", iov_len=260}], msg_iovlen=1, msg_controllen=0,
44+
```
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# D-Bus
2+
3+
D-Bus is an Inter-Process Communication (IPC) mechanism that is commonly present on Linux.
4+
It is particularly used by various components of the desktop environment (like GNOME) to communicate between one another, although the system itself is general-purpose and can be used in any other situations.
5+
6+
As the name suggests, the communication model is that of a bus: processes connect to the bus, then exchange messages with other processes through the bus.
7+
The bus itself is implemented by the dbus-daemon, and there are in fact multiple buses: one system bus, accessible system-wide, and one or more session buses, each one corresponding to one user login session.
8+
9+
Every process that connects to D-Bus receives a unique connection name.
10+
This name can be something human-readable, like `org.freedesktop.Notifications`, or some generated ID, like `:1.63`.
11+
Once a process is connected, it can expose one or multiple `objects`.
12+
An object has a path-like name, consisting of strings separated by a slash character (for example, `/org/freedesktop/Notifications`).
13+
Each object contains one or more `interfaces`, which have the methods that can be called on that object.

content/chapters/app-interact/lab/quiz/cgroups-vs-namespaces.md chapters/app-interact/os-cloud/drills/questions/cgroups-vs-namespaces.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Cgroups versus namespaces
1+
# Cgroups Versus namespaces
22

33
## Question Text
44

content/chapters/app-interact/lab/quiz/container-vs-vm.md chapters/app-interact/os-cloud/drills/questions/container-vs-vm.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Container versus VM
1+
# Container Versus VM
22

33
## Question Text
44

0 commit comments

Comments
 (0)