489 lines
15 KiB
Plaintext
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}.
|
|
"
|