Merge pull request #1732 from anderbubble/ps1-working-directory

Update PS1 during `wwctl image shell` to include working directory
This commit is contained in:
Christian Goll
2025-02-14 09:10:13 +01:00
committed by GitHub
3 changed files with 49 additions and 7 deletions

View File

@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Added `UniqueField` template function. #829
- Added `wwctl image build --syncuser`. #1321
- Added support for a DNSSEARCH netdev tag in network configuration overlays. #1256
- Added `WW_HISTFILE` to control shell history location during `wwctl image shell`. #1732
### Changed
@@ -25,6 +26,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- syncuser overlay skips duplicate users and groups in passwd and group databases. #829
- `wwctl image syncuser --write` is true by default. #1736
- Update syncuser documentation. #1736
- Update PS1 during `wwctl image shell` to include working directory by default,
and to include `PS1` from the environment if present. #1245
### Fixed

View File

@@ -20,8 +20,6 @@ import (
"github.com/warewulf/warewulf/internal/pkg/wwlog"
)
const exitEval = `$(VALU="$?" ; if [ $VALU == 0 ]; then echo write; else echo discard; fi)`
func CobraRunE(cmd *cobra.Command, args []string) (err error) {
if os.Getpid() != 1 {
return fmt.Errorf("PID is not 1: %d", os.Getpid())
@@ -78,7 +76,7 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) {
if err != nil {
return fmt.Errorf("failed to mount: %w", err)
}
ps1Str := fmt.Sprintf("[%s|%s] Warewulf> ", imageName, exitEval)
ps1Prefix := fmt.Sprintf(`[warewulf:%s]`, imageName)
if len(lowerObjects) != 0 && nodename == "" {
options := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s",
path.Join(runDir, "lower"), imagePath, path.Join(runDir, "work"))
@@ -114,11 +112,11 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) {
if err != nil {
return fmt.Errorf("couldn't create overlay for node render overlay: %s", err)
}
ps1Str = fmt.Sprintf("[%s|ro|%s] Warewulf> ", imageName, nodename)
ps1Prefix = fmt.Sprintf(`warewulf:%s(ro)] `, imageName)
}
if !image.IsWriteAble(imageName) && nodename == "" {
wwlog.Verbose("mounting %s ro", imagePath)
ps1Str = fmt.Sprintf("[%s|ro] Warewulf> ", imageName)
ps1Prefix = fmt.Sprintf(`warewulf:%s(ro)] `, imageName)
err = syscall.Mount(imagePath, imagePath, "", syscall.MS_BIND, "")
if err != nil {
return fmt.Errorf("failed to prepare bind mount: %w", err)
@@ -172,9 +170,25 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) {
return fmt.Errorf("failed to mount /run: %w", err)
}
os.Setenv("PS1", ps1Str)
os.Setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin")
os.Setenv("HISTFILE", "/dev/null")
var ps1Base string
if v, ok := os.LookupEnv("WW_PS1"); ok {
ps1Base = v
} else {
ps1Base = `\w\$ `
os.Setenv("WW_PS1", ps1Base)
}
os.Setenv("PS1", fmt.Sprintf("%s %s", ps1Prefix, ps1Base))
var histfile string
if v, ok := os.LookupEnv("WW_HISTFILE"); ok {
histfile = v
} else {
histfile = "/dev/null"
os.Setenv("WW_HISTFILE", histfile)
}
os.Setenv("HISTFILE", histfile)
wwlog.Debug("Exec: %s %s", args[1], args[1:])
return syscall.Exec(args[1], args[1:], os.Environ())

View File

@@ -291,6 +291,31 @@ If the files ``/etc/passwd`` or ``/etc/group`` were updated, there
will be an additional check to confirm if the users are in sync as
described in `Syncuser`_ section.
Specifying a prompt
-------------------
Warewulf sets a custom prompt during a ``wwctl image shell`` session. This
prompt may be customized using the ``WW_PS1`` variable, which is used to
construct the final ``PS1`` variable for the shell.
.. code-block::
# wwctl image shell rockylinux-9
[warewulf:rockylinux-9] /#
# env WW_PS1="\u@\h:\w\$ " wwctl image shell rockylinux-9
[warewulf:rockylinux-9] root@rocky:/$
Shell history
-------------
By default, Warewulf image shell sessions don't retain history; but you can
specify a history file by specifing ``WW_HISTFILE``. Note that this file is
stored within the image; you may want to exclude it when the image is built.
(See :ref:`exclude`.)
.. _exclude:
Excluding Files from an Image
-----------------------------