-
Notifications
You must be signed in to change notification settings - Fork 400
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
feat(assure_command_shell): assure proper installation of a shell #2368
base: master
Are you sure you want to change the base?
Conversation
busybox is also supported as a shell |
@LaszloGombos > busybox is also supported as a shell |
Thanks. 1./ In my mental model, In order to do this, you can try to introduce a new dracut "meta package" module for shell selection. Perhaps you can call it "sh" module. I hope you can model it after the dbus or network meta module. Please take a close look at #2181 for a good way to do this. Ideally this would result in moving the 2./ The current PR seems to be breaking test (and likely introducing regression). Please check test next time you upload the new revision of the PR. Thank you so much for taking this on. |
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.
Overall direction is great, but needs some cleanup
modules.d/00_sh/module-setup.sh
Outdated
# Assure a command shell. | ||
[[ " $add_dracutmodules $force_add_dracutmodules " == @(*\ dash\ *|*\ bash\ *|*\ mksh\ *|*\ busybox\ *) ]] || { | ||
shells='dash bash mksh busybox' | ||
_shell=$(realpath -e /bin/sh) |
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.
dracut -m "bash"
--> should install bash into initramfs regardless if what /bin/sh points to on the host
dracut -m "sh"
--> should pick the dracut module based on what /bin/sh points to on the host
dracut -m "sh bash"
--> should result in same initramfs as dracut -m "bash"
--> should install bash into initramfs regardless if what /bin/sh points to on the host
dracut -m "sh dash bash"
--> should install both dash and bash into initramfs regardless if what /bin/sh points to on the host (it is not clear to me what would be the deterministic rule for "${initdir}/bin/sh" to point to in this scenario, but this is an existing issue and not in scope for this PR". It might be that in this scenario the order of dracut modules on the command line is significant.)
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.
The refactored PR meets the above intentions without requiring the user to request the meta module. It operates automatically.
modules.d/00_sh/module-setup.sh
Outdated
|
||
# Prerequisite check(s) for module. | ||
check() { | ||
|
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.
Existing modules might be already forcing particular shells, so you should be checking for that.
This can be done with the following pattern:
for module in $shells; do
if dracut_module_included "$module"; then
_shell="$module"
break
fi
done
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.
The refactored PR respects the shell requests of other modules.
modules.d/00_sh/module-setup.sh
Outdated
} | ||
|
||
# Module dependency requirements. | ||
depends() { |
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.
depends()
function should return the shell selected. To keep it simple, maybe move all of the code from check()
to depends()
. check()
could always just return 255 unconditionally (as long as base module marks it as a dependency).
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.
'depends() function should return the shell selected.' This is achieved if needed.
The 99base module only expects that some shell be installed and linked to /bin/sh
. This is achieved.
modules.d/00bash/module-setup.sh
Outdated
inst /bin/bash | ||
|
||
# local - (available since bash-4.4 2016-09-15) automates the |
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.
You should remove all of these changes from the bash module from this PR, I think they will be confusing the reviewers. Please make a separate independent PR for the bash module change.
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.
00bash and 99squash module changes are included in separate commits.
They are needed to accomplish the intention of installing the command shell only after all installation conditions have been met.
modules.d/00_sh/module-setup.sh
Outdated
@@ -0,0 +1,33 @@ | |||
#!/bin/bash |
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.
Module should be called 00sh
not 00_sh
.
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.
The module name '99~sh' is required for proper ordering of the code.
It is a meta module enforcing some~shell—not to be confused with any current sh.
@@ -22,6 +22,7 @@ install() { | |||
inst_binary "${dracutbasedir}/dracut-util" "/usr/bin/dracut-util" | |||
ln -s dracut-util "${initdir}/usr/bin/dracut-getarg" | |||
ln -s dracut-util "${initdir}/usr/bin/dracut-getargs" | |||
[[ -L /bin/sh ]] || ln -sf dash /bin/sh |
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.
instead of this line, just make test-root module dependent on the "dash" module
depends() {
echo "dash debug"
}
Another PR is also making the same change for somewhat different reasons - #2354 . It is good to align on this between PRs.
This change might not even be necessary if you fix the dependency for the base module (see below).
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.
This seems to have been resolved.
inst_multiple bash | ||
(ln -s bash "${initdir}/bin/sh" || :) | ||
fi | ||
|
||
# add common users in /etc/passwd, it will be used by nfs/ssh currently |
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.
Glad we can remove this now, but you should also make the base module dependent on the new "sh" module, like the following
depends() {
echo "sh udev-rules"
}
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.
This is not needed with the refactored approach.
By chance I just run into the following (non-fatal) error running the following fro ma git checkout
Just wondering would this PR also resolve this (as it moves some code into dracut module itself) ? |
@LaszloGombos re: |
This is what I would recommend for Let's try to keep this simple first and just introduce the concept of a new module without adding a bunch of additional use-cases
|
This issue is being marked as stale because it has not had any recent activity. It will be closed if no further activity occurs. If this is still an issue in the latest release of Dracut and you would like to keep it open please comment on this issue within the next 7 days. Thank you for your contributions. |
@FGrose Do you plan on working on this PR more based on feedback from @LaszloGombos ? I am asking because I am also available try to help with this PR. Thank you @FGrose . |
@Henrik66 - Yes, I have a refactoring that I am testing now. |
I am very sad to see a completly new complex rewrite instead of iterating over the previous version. In order for this to ever land, we would need two independent approvals for:
Can you please elaborate why it is not possible to solve this problem without introducing a new module interface ? What would be a use case that would fail without this complex modification in the core logic of dracut. Do you see any use-case of postprocessing for any other dracut modules ? @Henrik66 If you still interested I think you should explore #2368 (comment). That should at least make it easier to compare and contrast the two solutions. |
@FGrose Perhaps can you make an independent PR just for
This PR is simply too big and impacts too many parts and people for it to ever land with our current processes. |
Provide code for postprocessing the build after all modules have been loaded by enrolling those modules with a postprocess() function in their module_setup.sh into the variable $mods_to_postprocess. Update the documentation in dracut.modules.7.asc and HACKING.md files. Also, include a missing dinfo message before including modules. This feature is demonstrated in three upcoming commits: feat(99~no~sh): allow a build without any command shell fix(00bash): fail if Bash below version 4.4 is linked to /bin/sh refactor(99squash): gather code into the squash module
Introduce a new meta module '99~sh' and assure that its depends() function runs at the end of the 'for_each_module_dir()' loop by using LC_COLLATE=C in that function so that the '99~sh' meta module sorts after other normally named modules. Background: Implicit installation of command shells may occur during the *** Resolving executable dependencies *** phase of dracut.sh with the default flag $DRACUT_RESOLVE_LAZY=1. Any module script file with a shebang interpreter directive will trigger the installation of that command interpreter, typically /bin/sh, unless that interpreter has already been installed. Such implicit installations bypass any conditions encoded in their dracut module dependency checks and should be precluded. If the dracut -m, --modules option is used (outside of -m 'auto'), no module-setup.sh level code is invoked during the 'for_each_module_dir check_module' loop for any modules other than those specified in the -m option arguments. For this reason, in this case invoke module_depends ~sh. To allow an initramfs to be built without any command shell, as currently allowed (such as when the -m option is used or when incrementally building the initramfs with --rebuild), a new meta module '99~no~sh' will be introduced in a following commit.
Install a null link to /bin/sh in order to satisfy the executable dependency checks and remove it in a postprocess() function. A no-command-shell-build may be desired when the -m, --modules option is used or when incrementally building an initramfs with --rebuild. This module provides an opt-out to the automatic specification of a command shell introduced with 99~sh.
At least bash-4.4 (from 2016-09-15) is required for proper xtrace logging when Bash is the initramfs command shell. This requirement was introduced in commit 10cf8e4 on 2022-12-30 with the feature, local -, which automates the restoration of local xtrace & other set options.
Move squash-module-specific code from dracut.sh to /99squash/module-setup.sh. Use dracut's new module_postprocess() feature. Make shell installation explicit, preferring busybox, if available. Clarify a comment about the dracut directory files. Also, make new shellcheck adjustments.
Only include bash into the generated initramfs if a dracut module explicitly depends on it. Implemented as a new dracut module that picks busybox shell on alpine. Based on the idea discussed upstream: dracutdevs/dracut#2368 (comment)
Introduce a new meta module, 99~sh, that will check that a command shell has been specified after module checks have been performed and before executable dependencies are checked. This avoids implicit installations of a command shell that skip the dracut module checks that the shell might need.
This PR now includes 5 commits to implement the feature:
2 (indirectly) and 3, 4, & 5 above use the postprocessing feature directly to achieve the intention.
Completes fix to #1530 augmenting #1534.
An alternative command shell, for example, zsh can be installed by providing an appropriate
module-setup.sh
at../modules.d/00zsh/
and running dracut withln -sf zsh /bin/sh
.Checklist