Skip to content

[common-utils] - append shell history functionality - #1026 #1157

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

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
7cbb7de
[common-utils] - append shell history functionality - #1026
gauravsaini04 Oct 22, 2024
412d221
Merge branch 'devcontainers:main' into features_#1026_shellhistory_in…
gauravsaini04 Oct 24, 2024
3076345
[common-utils] - added working shell history preserving logic for onl…
gauravsaini04 Nov 3, 2024
76d048b
change to mounts formatting
gauravsaini04 Nov 3, 2024
192e4f0
changes as suggested
gauravsaini04 Nov 5, 2024
930050d
changed path of source for bind mount
gauravsaini04 Nov 5, 2024
6970923
changes to path yet again for source of bind mount
gauravsaini04 Nov 5, 2024
5c7b513
change
gauravsaini04 Nov 5, 2024
753ab15
point to correct source dir
gauravsaini04 Nov 5, 2024
d21cc08
small change to path of source file
gauravsaini04 Nov 5, 2024
e48c1c0
change
gauravsaini04 Nov 5, 2024
10747ff
check root folder
gauravsaini04 Nov 5, 2024
581e5eb
change
gauravsaini04 Nov 5, 2024
54119e3
misc
gauravsaini04 Nov 5, 2024
dd34103
path correction final
gauravsaini04 Nov 5, 2024
ba649cf
change
gauravsaini04 Nov 5, 2024
c1b37fa
try
gauravsaini04 Nov 5, 2024
c227dc8
c
gauravsaini04 Nov 5, 2024
1de5f38
s
gauravsaini04 Nov 5, 2024
50ff6d2
hi
gauravsaini04 Nov 5, 2024
129f6bf
fin
gauravsaini04 Nov 5, 2024
c7c5aa8
c
gauravsaini04 Nov 5, 2024
3f1e7c9
Update devcontainer-feature.json
gauravsaini04 Nov 6, 2024
be92e63
giving due permissions before mounts is called for file move
gauravsaini04 Nov 8, 2024
dec0296
few changes
gauravsaini04 Nov 14, 2024
261428f
change
gauravsaini04 Nov 14, 2024
d6ba404
Merge branch 'devcontainers:main' into features_#1026_shellhistory_in…
Kaniska244 Dec 6, 2024
8406068
Updated shell history changes for PR#1157
Kaniska244 Dec 6, 2024
f8a5099
Updated shell history test scenarios in allow_shell_history.sh file
Kaniska244 Dec 10, 2024
ddcf3ae
Correcting the devcontainer-feature.json file
Kaniska244 Dec 10, 2024
f95f1f6
Fixing allow_shell_history issue
Kaniska244 Dec 10, 2024
eaa03c2
few changes for check correction
gauravsaini04 Dec 12, 2024
6c12229
misc change
gauravsaini04 Dec 13, 2024
c081194
misc change
gauravsaini04 Dec 13, 2024
da0ae0e
misc change for docker commands to work in test case
gauravsaini04 Dec 13, 2024
abac4e4
misc changes
gauravsaini04 Dec 13, 2024
aac0274
Merge branch 'main' into features_#1026_shellhistory_in_common-utils_…
gauravsaini04 Jan 28, 2025
e2c56d1
Merge branch 'main' into features_#1026_shellhistory_in_common-utils_…
gauravsaini04 Jan 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions src/common-utils/devcontainer-feature.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,31 @@
"type": "boolean",
"default": false,
"description": "Add packages from non-free Debian repository? (Debian only)"
},
"allowShellHistory": {
"type": "boolean",
"default": false,
"description": "Preserve shell history across dev container instances? (Currently supports bash, zsh, and fish)"
}
}
}
},
"containerEnv": {
"DOCKER_BUILDKIT": "1"
},
"postCreateCommand": "export DEVCONTAINER_ID=${devcontainerId} && . /etc/setup_history.sh",
"mounts": [{
"source": "devcontainers",
"target": "/devcontainers",
"type": "volume"
},
{
"source": "dind-var-lib-docker-${devcontainerId}",
"target": "/var/lib/docker",
"type": "volume"
},
{
"source": "/var/run/docker.sock",
"target": "/var/run/docker.sock",
"type": "bind"
}],
"entrypoint": "/usr/local/share/docker-init.sh"
}
15 changes: 15 additions & 0 deletions src/common-utils/main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ USERNAME="${USERNAME:-"automatic"}"
USER_UID="${USERUID:-"automatic"}"
USER_GID="${USERGID:-"automatic"}"
ADD_NON_FREE_PACKAGES="${NONFREEPACKAGES:-"false"}"
ALLOW_SHELL_HISTORY="${ALLOWSHELLHISTORY:-"false"}"

MARKER_FILE="/usr/local/etc/vscode-dev-containers/common"

Expand Down Expand Up @@ -567,6 +568,20 @@ if [ "${INSTALL_ZSH}" = "true" ]; then
fi
fi

# *********************************
# ** Enable shell history **
# *********************************

echo export ALLOW_SHELL_HISTORY="${ALLOW_SHELL_HISTORY}" > /etc/env.sh
echo export user_home="${user_home}" >> /etc/env.sh
echo export USERNAME="${USERNAME}" >> /etc/env.sh

chown "$USERNAME":"$USERNAME" "/etc/env.sh"
chmod u+rx "/etc/env.sh"

cp -f "${FEATURE_DIR}/scripts/setup_history.sh" /etc/setup_history.sh
chmod +x /etc/setup_history.sh

# *********************************
# ** Ensure config directory **
# *********************************
Expand Down
44 changes: 44 additions & 0 deletions src/common-utils/scripts/setup_history.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/sh

set -e

# Source the environment variables from env.sh
if [ -f /etc/env.sh ]; then
echo "importing values from env.sh.."
. /etc/env.sh
else
echo "env.sh not found!"
fi

if [ "${ALLOW_SHELL_HISTORY}" = "true" ]; then
echo "Activating feature 'shell-history'"
echo "User: ${USERNAME} User home: ${user_home}"

echo "Creating sub-folder with ${DEVCONTAINER_ID}.."

# Create the shell history directory in the mounted volume
BASE_HISTORY_DIR="/devcontainers"
HISTORY_DIR="${BASE_HISTORY_DIR}/${DEVCONTAINER_ID}/shellHistory"
USER_HISTORY_FILE="${user_home}/.bash_history"
VOLUME_HISTORY_FILE="${HISTORY_DIR}/.bash_history"

# Create the history directory in the volume, if it doesn’t already exist
sudo mkdir -p "${HISTORY_DIR}"
sudo chown -R "${USERNAME}" "${HISTORY_DIR}"
sudo chmod -R u+rwx "${HISTORY_DIR}"

# Ensure the volume's history file exists and set permissions
sudo touch "${VOLUME_HISTORY_FILE}"
sudo chown -R "${USERNAME}" "${VOLUME_HISTORY_FILE}"
sudo chmod -R u+rwx "${VOLUME_HISTORY_FILE}"

# Symlink for Bash history
sudo ln -sf ${USER_HISTORY_FILE} ${VOLUME_HISTORY_FILE}

# Configure immediate history saving to the volume
if ! grep -q "PROMPT_COMMAND" "${user_home}/.bashrc"; then
echo 'PROMPT_COMMAND="history -a; history -r;"' >> "${user_home}/.bashrc"
fi

echo "Shell history setup for history persistence amongst active containers is complete."
fi
124 changes: 124 additions & 0 deletions test/common-utils/allow_shell_history.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/bin/bash

set -e

# Optional: Import test library
source dev-container-features-test-lib

# Name of the generated script file
SCRIPT_NAME="build_and_run.sh"

# Dynamically write the script to a file
cat > $SCRIPT_NAME <<'EOF'
#!/bin/bash

# Parameters
BASE_IMAGE=${1:-"ubuntu:latest"}
IMAGE_NAME=${2:-"custom-image"}

cat > setup_history.sh <<EOL
#!/bin/sh

set -e

echo "Activating feature 'shell-history'"
echo "User: vscode User home: /home/vscode"

echo "Creating sub-folder with random folder named python-app.."

# Create the shell history directory in the mounted volume
HISTORY_DIR=/devcontainers/python-app/shellHistory
USER_HISTORY_FILE=/home/vscode/.bash_history
VOLUME_HISTORY_FILE=/devcontainers/python-app/shellHistory/.bash_history

# Create the history directory in the volume, if it doesn’t already exist
sudo mkdir -p /devcontainers/python-app/shellHistory
sudo chown -R vscode /devcontainers/python-app/shellHistory
sudo chmod -R u+rwx /devcontainers/python-app/shellHistory

# Ensure the volume's history file exists and set permissions
sudo touch /devcontainers/python-app/shellHistory/.bash_history
sudo chown -R vscode /devcontainers/python-app/shellHistory/.bash_history
sudo chmod -R u+rwx /devcontainers/python-app/shellHistory/.bash_history

# Symlink for Bash history
sudo ln -sf /home/vscode/.bash_history /devcontainers/python-app/shellHistory/.bash_history

# Configure immediate history saving to the volume
if ! grep -q "PROMPT_COMMAND" "/home/vscode/.bashrc"; then
echo 'PROMPT_COMMAND="history -a; history -r;"' >> "/home/vscode/.bashrc"
fi

echo "Shell history setup for history persistence amongst active containers is complete."
EOL

# Create entrypoint script
cat > entrypoint.sh <<EOL
#!/bin/bash

# Log entrypoint execution
echo "Executing entrypoint script..." > /var/log/entrypoint.log

# Execute setup history script
chmod +x /usr/local/bin/setup_history.sh >> /var/log/entrypoint.log 2>&1
/usr/local/bin/setup_history.sh >> /var/log/entrypoint.log 2>&1

# Keep the container running
tail -f /dev/null
EOL

# Create Dockerfile
cat > Dockerfile <<EOL
FROM $BASE_IMAGE
RUN apt-get update && apt-get install -y curl git sudo
COPY setup_history.sh /usr/local/bin/setup_history.sh
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["bash"]
EOL

# Build and tag the image
sudo docker build -t $IMAGE_NAME .

# Run the container again for attaching volume
CONTAINER_ID=$(sudo docker run -v devcontainers:/devcontainers -itd $IMAGE_NAME) > /dev/null

# Output the container ID to a file
echo "CONTAINER_ID=$CONTAINER_ID" > /tmp/container_id.txt

echo "Started container: $CONTAINER_ID"
EOF

# Make the generated script executable
chmod +x $SCRIPT_NAME
./$SCRIPT_NAME "mcr.microsoft.com/devcontainers/python:latest" "python-app"

# Function to add shell history
add_shell_history() {
local container_id=$1
local history_message=$2
echo -e "\nWriting shell history: $history_message";
sudo docker exec -i $container_id /bin/bash -c "echo \"$history_message\" >> ~/.bash_history"
}

# Function to check shell history
check_shell_history() {
local container_id=$1
echo -e "\nChecking shell history from container: ";
sudo docker exec -i $container_id /bin/bash -c "cat ~/.bash_history"
}

source /tmp/container_id.txt

# Start the container and add shell history
sudo docker start $CONTAINER_ID > /dev/null
add_shell_history $CONTAINER_ID "Shell History for First Container Created."
sudo docker stop $CONTAINER_ID > /dev/null

# Start the container and check shell history persistence
sudo docker start $CONTAINER_ID > /dev/null
check_shell_history $CONTAINER_ID

# Report result
reportResults
16 changes: 16 additions & 0 deletions test/common-utils/scenarios.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
{
"allow_shell_history": {
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"docker-in-docker": {},
"common-utils": {
"installZsh": true,
"allowShellHistory": true
}
},
"overrideFeatureInstallOrder": [
"./common-utils",
"./docker-in-docker"
],
"remoteUser": "vscode",
"containerUser": "vscode"
},
"bionic": {
"image": "ubuntu:bionic",
"remoteUser": "devcontainer",
Expand Down