loongbedrocklinux-userlandd/src/slash-bedrock/share/brl-tutorial/lessons/001_basics

489 lines
15 KiB
Plaintext

#!/bedrock/libexec/busybox sh
#
# brl tutorial basic
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 2 as published by the Free Software Foundation.
#
# Copyright (c) 2019-2020 Daniel Thau <danthau@bedrocklinux.org>
#
# Bedrock Linux basics tutorial
# shellcheck source=src/slash-bedrock/share/brl-tutorial/common
. /bedrock/share/brl-tutorial/common
if [ "${*}" = "help" ]; then
echo "Bare minimum users are expected to know about Bedrock Linux"
return
fi
section "${brl_tutorial}" "
Welcome to the ${Bedrock_Linux} basics tutorial.
This tutorial will introduce you to the minimum ${Bedrock_Linux}-specific
background required to utilize and manage a ${Bedrock} system.
$(standard_intro)
"
section "${Strata}" "
A ${Bedrock} system is composed of ${strata}, which are collections of
interrelated files and processes. These typically correspond to Linux distro
installs: one may have a ${Debian} ${stratum}, an ${Arch} ${stratum}, etc.
${Bedrock} integrates these into a single, largely cohesive system. Run
$(cmd "brl list")
to see a list of ${strata} currently being integrated together.
$(
if [ "$(brl list | wc -l)" -le 2 ]; then
printf "This appears to be a fresh Bedrock Linux install with two ${strata}:
- ${bedrock}, which is the ${stratum} providing ${Bedrock}-specific functionality.
- ${init_stratum} which currently provides everything else.
This isn't much more interesting than ${init_stratum} would have been by itself.
"
else
printf "This system appears to already have a number of ${strata}, including:
- ${bedrock}, which is the ${stratum} providing ${Bedrock}-specific functionality.
- ${init_stratum}, which is currently providing your init system.
amongst others.
"
fi
)
The ${brl_fetch} command can be used to acquire new ${strata}. To see distros
${brl_fetch} knows how to acquire, run
$(cmd "brl fetch --list")
Let's get a couple more ${strata} to experiment with in this tutorial:
$(rcmd "brl fetch -n tut-alpine alpine")
$(rcmd "brl fetch -n tut-void void")
" "brl list | grep \"^tut-alpine\$\" && brl list | grep \"^tut-void\$\""
section "Cross-${stratum} commands" "
Many features from the ${strata} we just acquired should work just as they
would in their normal environments. For example, since we now have an
${Alpine} ${stratum}, we can run ${Alpine}'s ${apk} package manager directly on
the command line:
$(cmd "apk --help")
We also have a ${Void} ${stratum} providing ${xbps_install}:
$(cmd "xbps-install --help")
We can install ${Alpine}'s ${jq} and ${Void}'s ${jo}:
$(rcmd "apk add jq")
$(rcmd "xbps-install -y jo")
Importantly, the commands can interact just as they would were they from the
same distro:
$(cmd "jo \"distro=bedrock\" | jq \".distro\" | tee ${tmpfile}")
" "grep bedrock ${tmpfile}"
section "Other cross-${stratum} features" "
${Bedrock} integrates more than just terminal commands. It strives to make as
much as it can work transparently and cohesively across ${strata}, including:
- Graphical application menu contents
- Shell tab completion
- Kernel firmware detection
- Xorg fonts
- Some themes
Lets try another example: ${man} pages. We can get ${Alpine}'s ${jq} ${man}
page and ${Void}'s ${man} executable:
$(rcmd "apk add jq-doc")
$(rcmd "xbps-install -y man")
Then have ${Void}'s ${man} read ${Alpine}'s ${jq} documentation:
$(cmd "man jq | head | tee ${tmpfile}")
" "grep jq ${tmpfile}"
section "${brl_which}" "
On a ${Bedrock} system, every file and every process is associated with some
${stratum}. The ${brl_which} command can be used to query ${Bedrock} for this
association. Lets try it:
Which ${strata} provide the ${apk} and ${xbps_install} commands?
$(cmd "brl which apk")
$(cmd "brl which xbps-install")
What about commands that multiple ${strata} - ${bedrock}, ${tut_alpine}, ${tut_void},
$(
if strat -r init /bedrock/libexec/busybox which ls >/dev/null 2>&1; then
printf "${init_stratum}, "
fi
)etc - all provide, such as ${ls}?
$(cmd "brl which ls")
Makes sense it has to pick a ${stratum} here, but why that one? Keep this
question in mind, as it will be answered later in the tutorial.
Which ${strata} provide PID 1 (the init system) and PID $$ (this tutorial)?
$(cmd "brl which 1")
$(cmd "brl which $$")
Which stratum provides ${color_file}/${color_norm}, the root directory?
$(cmd "brl which /")
Again, sure it has to pick one, but why that specific ${stratum} for the root
directory that multiple ${strata} provide? Like the ${ls} situation, this will
be answered soon enough.
Which ${stratum} provides ${bedrock_etc_bedrock_conf}, the ${Bedrock} configuration
file?
$(cmd "brl which /bedrock/etc/bedrock.conf")
Wait - that last command output ${global}, but ${color_alert}we do not have a such a ${stratum}:${color_norm}
$(cmd "brl list | grep global")
What's going on here?
"
section "File path types: ${local}" "
To avoid conflicts, processes from one ${stratum} may see their own
${stratum}'s instance of a given file (or lack of file) at a given file path.
This is why the ${stratum} providing your shell:
$(cmd "brl which")
Sees its own root directory instead of another ${stratum}'s:
$(cmd "brl which /")
If your shell ${stratum} has a ${color_file}/etc/os-release${color_norm}, it
will probably correspond to your shell ${stratum} distro:
$(cmd "cat /etc/os-release")
This is needed to avoid conflicts. For example, ${Debian}'s ${apt} needs to
see ${Debian} mirrors at ${etc_apt_sources_list} and ${Ubuntu}'s ${apt} needs
to see ${Ubuntu}'s mirrors at the same path. If they saw the same contents in
${sources_list} these two programs would conflict with each other.
In ${Bedrock} terminology, these file paths are described as ${local}.
"
section "File path types: ${global}" "
If all paths were ${local}, ${strata} would be unable to interact with each
other. For ${strata} to interact, there are also ${global} paths: file paths
where every ${stratum} sees the same content. Under-the-hood, these are
${bedrock} files which are being shared with other ${strata}.
For example, all ${strata} see the same contents in ${run} to communicate over
common sockets:
$(cmd "brl which /run")
Directories like ${home} and ${tmp} are also ${global}. You can have software
from one ${stratum}, like ${Alpine}'s ${jq}, read files created by another
${stratum}, like ${Void}'s ${jo}, provided the file is in a ${global} location:
$(cmd "brl which /tmp")
$(cmd "jo \"path=global\" > ${tmpfile}")
$(cmd "jq \".path\" < ${tmpfile} | tee ${tmpfile2}")
" "grep global ${tmpfile2}"
section "File path types: ${cross}" "
Sometimes processes from one ${stratum} need to access ${local} files from
another. This is achieved via ${cross} file paths.
If you want to read or write to a ${local} file specific to a given ${stratum},
prefix ${bedrock_strata}${color_sub}<stratum>${color_norm} to the file path to ${cross} to that
${stratum}:
$(cmd "brl which /bedrock/strata/bedrock/etc/os-release")
$(cmd "cat /bedrock/strata/bedrock/etc/os-release")
$(cmd "brl which /bedrock/strata/tut-alpine/etc/os-release")
$(cmd "cat /bedrock/strata/tut-alpine/etc/os-release")
"
section "${strat}" "
${bedrock_strata} is only suitable for reading and writing ${cross} files. To
execute a program from a specific ${stratum}, prefix \`${strat} ${color_sub}<stratum>${color_norm}\`.
For example, if you care about which ${ls} you want to run:
$(cmd "strat tut-alpine ls --help 2>&1 | head -n1")
$(cmd "strat tut-void ls --help 2>&1 | head -n1 ")
If you do not specify the desired ${stratum} with ${strat}, ${Bedrock} will try
to figure one out from context:
- If ${Bedrock} is configured to ensure one ${stratum} always provides the
given command, it will do so. For example, init related commands should always
correspond to the ${stratum} providing PID 1. This is called ${pinning}.
- If the command is not ${pinned} to a given ${stratum} but is available
${locally}, ${Bedrock} will utilize the ${local} one. This is to ensure
distro-specific dependency quirks are met.
- If the command is not ${pinned} and not available ${locally}, ${Bedrock}
assumes the specific build of the command does not matter. In these cases
${Bedrock} will search other ${strata} and supply the first instance of the
command it finds.
The first bullet point above is why ${reboot} comes from the init stratum:
$(cmd "brl which reboot")
$(cmd "brl which 1")
The second bullet point above is why the ${ls} you get if you do not specify
one with ${strat}:
$(cmd "brl which ls")
is probably from the same ${stratum} providing your shell:
$(cmd "brl which")
and the third rule above is why ${apk} and ${xbps_install} work despite being
from different ${strata}:
$(cmd "brl which apk")
$(cmd "brl which xbps-install")
"
section "${restriction}" "
Occasionally, software may become confused by ${Bedrock}'s environment. Most
notably this occurs when build tools scan the environment for dependencies and
find them from different distributions. To handle this situation, ${strat}'s
$(flag -r) flag may be used to ${restrict} the command from seeing ${cross}-${stratum} hooks.
For example, normally ${tut_void}'s shell can see ${tut_alpine}'s ${apk}:
$(cmd "strat tut-void sh -c 'apk --help'")
But if you ${restrict} it, it cannot, and this command will fail:
$(cmd "strat -r tut-void sh -c 'apk --help'")
${Bedrock} will automatically ${restrict} some commands that it knows are
related to compiling, such as ${Arch}'s ${makepkg}. If this is a problem for
any reason, you can un-${restrict} with ${strat} $(flag -u).
In general, if something acts oddly under ${Bedrock}, the first thing you
should try is to ${restrict} it. This is especially true when it comes to
compiling software.
"
section "${stratum} states" "
It is sometimes useful to have a ${stratum}'s files on disk without them being
integrated into the rest of the system. To do this, ${disable} the ${stratum}:
$(rcmd "brl disable tut-void")
This will stop all of the ${stratum}'s running processes and block the ability
to launch new ones. This command will now fail:
$(cmd "strat tut-void xbps-install --help")
The ${stratum} may be re-enabled:
$(rcmd "brl enable tut-void")
after which this command will now work:
$(cmd "strat tut-void xbps-install --help")
"
section "Updating" "
Strata are each responsible for updating themselves. To update ${tut_alpine}
we can tell its package manager to update:
$(rcmd "apk update && apk upgrade")
and to update ${tut_void} we can similarly instruct its package manager:
$(rcmd "xbps-install -Syu")
${bedrock} can be updated via ${brl}:
$(rcmd "brl update")
"
section "pmm" "
Manually updating all package managers as shown in the previous section may be a
bit tedious. Other multi-package-manager workflows, such as searching multiple
package managers to see which provides a package, that can also be tedious to
do by hand.
To resolve this, Bedrock provides a utility called ${pmm} which abstracts
multi-package-manager and cross-package-manager workflows.
pmm mimics the user interface of other package managers. Open
${bedrock_etc_bedrock_conf}
as root and find the user-interface field under the [pmm] section. Populate it
according to the surrounding comments if it is empty then run
$(rcmd "brl apply")
to set ${pmm}s user interface. Now explore
$(cmd "pmm --help")
or potentially
$(cmd "pmm-install --help")
depending on your configuration.
"
section "Removing ${strata}" "
As a protective measure, ${strata} may not be removed while ${enabled}. If you
wish to remove a ${stratum}, first ${disable} it.
$(rcmd "brl disable tut-alpine")
$(rcmd "brl remove tut-alpine")
If you know the target ${stratum} is ${enabled}, ${brl_remove} takes a
${color_cmd}-d${color_norm} flag to ${disable} prior to removing:
$(rcmd "brl remove -d tut-void")
" "! brl list -v | grep -e \"^tut-alpine$\" -e \"^tut-void$\""
section "Special ${strata}" "
The ${stratum} currently providing PID 1 (the init) may not be ${disabled}, as the
Linux kernel does not respond well to PID 1 dying. Given
$(cmd "brl which 1")
this command will fail:
$(rcmd "brl disable $(brl deref init)")
If you wish to remove the init-providing ${stratum}, first reboot and select
another ${stratum} to provide your init for the given session.
The ${bedrock} ${stratum} glues the entire system together. It is the only
${stratum} which may not be removed.
$(
if hijacked_stratum="$(brl deref hijacked 2>&1)"; then
hijacked_stratum="${color_strat}${hijacked_stratum}${color_norm}"
printf "
When ${Bedrock} ${hijacked} this computer, it:
- Moved the previous install files elsewhere.
- Installed itself to the root of the system.
- Added the previous install as a new ${stratum} called ${hijacked_stratum}.
Now that the ${hijack} operation has completed, there is nothing particularly
special about the ${hijacked_stratum} ${stratum}. You are free to remove it,
should you wish to do so. Just make sure to install anything essential that
${hijacked_stratum} is providing, such as the bootloader or kernel or ${sudo},
in another ${stratum}.
"
fi
)
"
section "brl import" "
If you would like to make a ${stratum} from some distro that ${brl_fetch} does
not support, you may use the ${brl_import} command to do so.
Get the desired files in some format such as:
- directory containing desired files
- tarball containing desired files
- Virtual Machine image (e.g. .qcow, .vdi, .vmdk)
then run
$(rcmd "brl import <name> </path/to/source>")
"
section "${bedrock_conf}" "
All ${Bedrock} configuration is placed in a single file,
${bedrock_etc_bedrock_conf}. If it seems like something ${Bedrock} does should
be configurable, look in there. After making changes to ${bedrock_conf} run
${brl_apply} to ensure they take effect.
For example, run
$(cmd "brl --help")
$(
if [ "$(cfg_value "miscellaneous" "color")" = "true" ]; then
printf "and notice how pretty and colorful the output is.
Now open ${bedrock_etc_bedrock_conf} and find
${color_file}color = true${color_norm}
towards the bottom and change it to
${color_file}color = false${color_norm}
and apply that change:
$(rcmd "brl apply")
Now run
$(cmd "brl --help")
and notice how boring and monotone the output is.
"
else
printf "and notice how boring and monotone the output is.
Now open ${bedrock_etc_bedrock_conf} and find
${color_file}color = [...]${color_norm}
towards the bottom and change it to
${color_file}color = true${color_norm}
and apply that change:
$(rcmd "brl apply")
Now run
$(cmd "brl --help")
and notice how pretty and colorful the output is.
"
fi
)
Finally, change the ${bedrock_conf} setting back and
$(rcmd "brl apply")
again to reset everything to how it was before.
"
section "${brl}" "
Most operations used to manage ${Bedrock} can be found in the ${brl} command.
This includes both those discussed earlier in the tutorial as well as some
which were skipped for brevity.
After this tutorial, consider exploring ${brl}:
$(cmd "brl --help")
going through other tutorials:
$(cmd "brl tutorial --help")
or reading through ${bedrock_etc_bedrock_conf}.
"