@@ -37,36 +37,47 @@ data:
3737 echo "Setting up user: ${DEV_USERNAME}"
3838
3939 # Create/rename group with target GID
40- if id -g ${TARGET_GID} &>/dev/null; then
41- echo "Renaming group ${TARGET_GID} to ${DEV_USERNAME}"
42- groupmod -n ${DEV_USERNAME} $(id -gn ${TARGET_GID})
40+ if GROUP_ENTRY="$(getent group "${TARGET_GID}")"; then
41+ EXISTING_GROUP_NAME="${GROUP_ENTRY%%:*}"
42+ if [ "${EXISTING_GROUP_NAME}" != "${DEV_USERNAME}" ]; then
43+ echo "Renaming group ${EXISTING_GROUP_NAME} (GID: ${TARGET_GID}) to ${DEV_USERNAME}"
44+ groupmod -n "${DEV_USERNAME}" "${EXISTING_GROUP_NAME}"
45+ else
46+ echo "Group ${DEV_USERNAME} already exists with GID ${TARGET_GID}"
47+ fi
4348 else
4449 echo "Adding group ${DEV_USERNAME} with GID ${TARGET_GID}"
45- groupadd -g ${TARGET_GID} ${DEV_USERNAME}
50+ groupadd -g " ${TARGET_GID}" " ${DEV_USERNAME}"
4651 fi
4752
4853 # Create/rename user with target UID
49- if id -u ${TARGET_UID} &>/dev/null; then
50- echo "Renaming user ${TARGET_UID} to ${DEV_USERNAME}"
51- usermod -l ${DEV_USERNAME} -s /bin/bash -d /home/${DEV_USERNAME} -g ${TARGET_GID} $(id -un ${TARGET_UID})
54+ if USER_ENTRY="$(getent passwd "${TARGET_UID}")"; then
55+ EXISTING_USER_NAME="${USER_ENTRY%%:*}"
56+ if [ "${EXISTING_USER_NAME}" != "${DEV_USERNAME}" ]; then
57+ echo "Renaming user ${EXISTING_USER_NAME} (UID: ${TARGET_UID}) to ${DEV_USERNAME}"
58+ usermod -l "${DEV_USERNAME}" -s /bin/bash -d "/home/${DEV_USERNAME}" -g "${TARGET_GID}" "${EXISTING_USER_NAME}"
59+ else
60+ echo "User ${DEV_USERNAME} already exists with UID ${TARGET_UID}; ensuring shell/home/group settings"
61+ usermod -s /bin/bash -d "/home/${DEV_USERNAME}" -g "${TARGET_GID}" "${DEV_USERNAME}"
62+ fi
5263 else
5364 echo "Adding user ${DEV_USERNAME} with UID ${TARGET_UID}"
54- useradd -u ${TARGET_UID} - m -s /bin/bash ${DEV_USERNAME}
65+ useradd -u " ${TARGET_UID}" -g "${TARGET_GID}" - m -s /bin/bash " ${DEV_USERNAME}"
5566 fi
5667
5768 # Ensure home directory exists and has correct ownership
5869 mkdir -p "/home/${DEV_USERNAME}"
59- chown ${DEV_USERNAME}:${DEV_USERNAME} "/home/${DEV_USERNAME}"
70+ chown " ${DEV_USERNAME}:${DEV_USERNAME}" "/home/${DEV_USERNAME}"
6071
6172 echo "Section 2: User management complete"
6273
6374 # === ADMIN PRIVILEGES ===
6475 echo "Setting up admin privileges for ${DEV_USERNAME}"
65- usermod -aG sudo ${DEV_USERNAME}
76+ usermod -aG sudo " ${DEV_USERNAME}"
6677
6778 # Configure sudo to not require password
68- echo "${DEV_USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${DEV_USERNAME}
69- chmod 440 /etc/sudoers.d/${DEV_USERNAME}
79+ echo "${DEV_USERNAME} ALL=(ALL) NOPASSWD:ALL" > " /etc/sudoers.d/${DEV_USERNAME}"
80+ chmod 440 " /etc/sudoers.d/${DEV_USERNAME}"
7081
7182 echo "Section 3: Admin privileges complete"
7283
@@ -103,14 +114,24 @@ data:
103114 " > /home/${DEV_USERNAME}/.ssh/authorized_keys
104115 chmod 700 /home/${DEV_USERNAME}/.ssh
105116 chmod 600 /home/${DEV_USERNAME}/.ssh/authorized_keys
106- chown -R ${DEV_USERNAME}:${DEV_USERNAME} /home/${DEV_USERNAME}/.ssh
117+ chown -R " ${DEV_USERNAME}:${DEV_USERNAME}" " /home/${DEV_USERNAME}/.ssh"
107118
108119 echo "Section 5: SSH server setup complete"
109120
110121 # === PACKAGE INSTALLATION ===
111122 echo "Installing APT packages: vim curl"
112123 apt-get install -y vim curl
113124
125+ # Ensure default venv path exists before Python package installs.
126+ # This keeps the default pythonBinPath (/opt/venv/bin) functional on images
127+ # that don't pre-create /opt/venv.
128+ if [ "${PYTHON_BIN_PATH}" = "/opt/venv/bin" ] && [ ! -x "${PYTHON_PATH}" ]; then
129+ echo "Bootstrapping Python virtual environment at /opt/venv"
130+ apt-get install -y python3-venv
131+ python3 -m venv /opt/venv
132+ chown -R "${DEV_USERNAME}:${DEV_USERNAME}" /opt/venv
133+ fi
134+
114135 # Install common python packages from requirements.txt
115136 if [ -f /scripts/requirements.txt ]; then
116137 echo "Installing Python packages from requirements.txt"
@@ -122,6 +143,11 @@ data:
122143 echo "Section 6: Package installation complete"
123144
124145 # === USER ENVIRONMENT SETUP ===
146+ # Repair ownership across persisted home content before running user-level setup.
147+ # This prevents failures like ".bashrc: Permission denied" when stale files are
148+ # carried over from previous runs with mismatched UID/GID ownership.
149+ chown -R "${DEV_USERNAME}:${DEV_USERNAME}" "/home/${DEV_USERNAME}"
150+
125151 # Set up environment for the user
126152 if [ -f /scripts/setup.sh ]; then
127153 echo "Running user environment setup script"
@@ -146,8 +172,9 @@ data:
146172 # === VSCODE CONFIGURATION ===
147173
148174
149- # Make sure .vscode-server directory is owned by ${DEV_USERNAME}
150- chown -R ${DEV_USERNAME}:${DEV_USERNAME} /home/${DEV_USERNAME}/.vscode-server
175+ # Make sure .vscode-server directory exists and is owned by ${DEV_USERNAME}
176+ mkdir -p /home/${DEV_USERNAME}/.vscode-server
177+ chown -R "${DEV_USERNAME}:${DEV_USERNAME}" "/home/${DEV_USERNAME}/.vscode-server"
151178
152179 echo "Section 8: VSCode configuration complete"
153180
@@ -157,6 +184,7 @@ data:
157184 # === SSH SERVER LAUNCH ===
158185 echo "Starting SSH server"
159186 /usr/sbin/sshd -D
187+
160188
161189 # Static utility scripts - included as-is
162190 run_with_git.sh : |
0 commit comments