Compare commits

...

9 Commits

Author SHA1 Message Date
Chuck Butkus
a9a8e3e461 More logging 2025-08-28 02:01:37 -04:00
Chuck Butkus
0599f75713 Remove vscode username restriction 2025-08-28 00:37:14 -04:00
Chuck Butkus
16cc0433e3 Fix home directory 2025-08-28 00:04:56 -04:00
chuckbutkus
98fb3ab979 Merge branch 'main' into cbutkus-user 2025-08-27 23:33:30 -04:00
Chuck Butkus
41c4000d48 Fix bash username 2025-08-27 23:32:10 -04:00
Chuck Butkus
08c63b248d Add runtime user env vars 2025-08-27 23:01:36 -04:00
Chuck Butkus
1989f1c106 Fix USER commands 2025-08-27 21:51:02 -04:00
Chuck Butkus
dc5de98e8d Change user to cbutkus 2025-08-27 21:45:27 -04:00
Chuck Butkus
dba8b28824 Logging 2025-08-27 21:30:47 -04:00
5 changed files with 63 additions and 54 deletions

View File

@@ -37,15 +37,6 @@ class VSCodePlugin(Plugin):
)
return
if username not in ['root', 'openhands']:
self.vscode_port = None
self.vscode_connection_token = None
logger.warning(
'VSCodePlugin is only supported for root or openhands user. '
'It is not yet supported for other users (i.e., when running LocalRuntime).'
)
return
# Set up VSCode settings.json
self._setup_vscode_settings()

View File

@@ -193,9 +193,8 @@ class BashSession:
def initialize(self) -> None:
self.server = libtmux.Server()
_shell_command = '/bin/bash'
if self.username in ['root', 'openhands']:
# This starts a non-login (new) shell for the given user
_shell_command = f'su {self.username} -'
# This starts a non-login (new) shell for the given user
_shell_command = f'su {self.username} -'
# FIXME: we will introduce memory limit using sysbox-runc in coming PR
# # otherwise, we are running as the CURRENT USER (e.g., when running LocalRuntime)

View File

@@ -1,3 +1,6 @@
import os
import traceback
from openhands.core.config import OpenHandsConfig
from openhands.core.logger import openhands_logger as logger
from openhands.runtime.plugins import PluginRequirement
@@ -12,6 +15,9 @@ DEFAULT_PYTHON_PREFIX = [
]
DEFAULT_MAIN_MODULE = 'openhands.runtime.action_execution_server'
RUNTIME_USERNAME = os.getenv('RUNTIME_USERNAME')
RUNTIME_UID = os.getenv('RUNTIME_UID')
def get_action_execution_server_startup_command(
server_port: int,
@@ -23,10 +29,17 @@ def get_action_execution_server_startup_command(
main_module: str = DEFAULT_MAIN_MODULE,
python_executable: str = 'python',
) -> list[str]:
logger.info(
'get_action_execution_server_startup_command stack:\n%s',
''.join(traceback.format_stack()),
)
sandbox_config = app_config.sandbox
logger.debug(f'app_config {vars(app_config)}')
logger.debug(f'sandbox_config {vars(sandbox_config)}')
logger.debug(f'override_user_id {override_user_id}')
logger.info(f'app_config {vars(app_config)}')
logger.info(f'sandbox_config {vars(sandbox_config)}')
logger.info(f'RUNTIME_USERNAME {RUNTIME_USERNAME}, RUNTIME_UID {RUNTIME_UID}')
logger.info(
f'override_username {override_username}, override_user_id {override_user_id}'
)
# Plugin args
plugin_args = []
@@ -40,10 +53,15 @@ def get_action_execution_server_startup_command(
'--browsergym-eval-env'
] + sandbox_config.browsergym_eval_env.split(' ')
username = override_username or (
'openhands' if app_config.run_as_openhands else 'root'
username = (
override_username
or RUNTIME_USERNAME
or ('openhands' if app_config.run_as_openhands else 'root')
)
user_id = override_user_id or (1000 if app_config.run_as_openhands else 0)
user_id = (
override_user_id or RUNTIME_UID or (1000 if app_config.run_as_openhands else 0)
)
logger.info(f'username {username}, user_id {user_id}')
base_cmd = [
*python_prefix,
@@ -64,6 +82,6 @@ def get_action_execution_server_startup_command(
if not app_config.enable_browser:
base_cmd.append('--no-enable-browser')
logger.debug(f'get_action_execution_server_startup_command: {base_cmd}')
logger.info(f'get_action_execution_server_startup_command: {base_cmd}')
return base_cmd

View File

@@ -70,12 +70,12 @@ RUN (if getent passwd 1000 | grep -q pn; then userdel pn; fi) && \
(if getent group 1000 | grep -q ubuntu; then groupdel ubuntu; fi)
# Create openhands group and user
RUN groupadd -g 1000 openhands && \
useradd -u 1000 -g 1000 -m -s /bin/bash openhands && \
usermod -aG sudo openhands && \
echo 'openhands ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
RUN groupadd -g 1000 cbutkus && \
useradd -u 1000 -g 1000 -m -s /bin/bash cbutkus && \
usermod -aG sudo cbutkus && \
echo 'cbutkus ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
# Set empty password for openhands user to allow passwordless su
passwd -d openhands && \
passwd -d cbutkus && \
# Set empty password for root user as well to ensure su works in both directions
passwd -d root && \
# Ensure root can su to openhands without password by configuring PAM
@@ -86,7 +86,7 @@ RUN groupadd -g 1000 openhands && \
RUN mkdir -p /openhands && \
mkdir -p /openhands/logs && \
mkdir -p /openhands/poetry && \
chown -R openhands:openhands /openhands
chown -R cbutkus:cbutkus /openhands
# ================================================================
@@ -168,7 +168,7 @@ RUN if [ -z "${RELEASE_TAG}" ]; then \
mv ${RELEASE_TAG}-linux-${arch} ${OPENVSCODE_SERVER_ROOT} && \
cp ${OPENVSCODE_SERVER_ROOT}/bin/remote-cli/openvscode-server ${OPENVSCODE_SERVER_ROOT}/bin/remote-cli/code && \
rm -f ${RELEASE_TAG}-linux-${arch}.tar.gz && \
chown -R openhands:openhands ${OPENVSCODE_SERVER_ROOT}
chown -R cbutkus:cbutkus ${OPENVSCODE_SERVER_ROOT}
@@ -176,7 +176,7 @@ RUN if [ -z "${RELEASE_TAG}" ]; then \
{% macro install_vscode_extensions() %}
# Install our custom extensions as openhands user
USER openhands
USER cbutkus
RUN mkdir -p ${OPENVSCODE_SERVER_ROOT}/extensions/openhands-hello-world && \
cp -r /openhands/code/openhands/runtime/utils/vscode-extensions/hello-world/* ${OPENVSCODE_SERVER_ROOT}/extensions/openhands-hello-world/
@@ -207,11 +207,11 @@ RUN \
# Set proper permissions for shared access
chmod -R 755 /opt/playwright-browsers && \
# Create cache directories and symlinks for both users
mkdir -p /home/openhands/.cache && \
mkdir -p /home/cbutkus/.cache && \
mkdir -p /root/.cache && \
ln -sf /opt/playwright-browsers /home/openhands/.cache/ms-playwright && \
ln -sf /opt/playwright-browsers /home/cbutkus/.cache/ms-playwright && \
ln -sf /opt/playwright-browsers /root/.cache/ms-playwright && \
chown -h openhands:openhands /home/openhands/.cache/ms-playwright && \
chown -h cbutkus:cbutkus /home/cbutkus/.cache/ms-playwright && \
# Set environment variable for all users
echo 'export PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers' >> /etc/environment && \
{% endif %}
@@ -220,10 +220,10 @@ RUN \
# Set permissions for shared read-only access
chmod -R 755 /openhands/poetry && \
chmod -R 755 /openhands/micromamba && \
chown -R openhands:openhands /openhands/poetry && \
chown -R cbutkus:cbutkus /openhands/poetry && \
mkdir -p /openhands/workspace && chmod -R g+rws,o+rw /openhands/workspace && \
chown -R openhands:openhands /openhands/workspace && \
chown -R openhands:openhands /openhands/micromamba && \
chown -R cbutkus:cbutkus /openhands/workspace && \
chown -R cbutkus:cbutkus /openhands/micromamba && \
# Ensure PATH includes system binaries early in startup
echo 'export PATH="/usr/bin:/bin:/usr/sbin:/sbin:$PATH"' >> /etc/environment && \
echo 'export PATH="/usr/bin:/bin:/usr/sbin:/sbin:$PATH"' >> /etc/bash.bashrc && \
@@ -244,7 +244,7 @@ RUN \
# Install user-level dependencies as openhands user
WORKDIR /openhands/code
USER openhands
USER cbutkus
RUN \
/openhands/micromamba/bin/micromamba config set changeps1 False && \
/openhands/micromamba/bin/micromamba run -n openhands poetry config virtualenvs.path /openhands/poetry && \
@@ -271,7 +271,7 @@ RUN mkdir -p /openhands/micromamba/bin && \
/bin/bash -c "PREFIX_LOCATION=/openhands/micromamba BIN_FOLDER=/openhands/micromamba/bin INIT_YES=no CONDA_FORGE_YES=yes $(curl -L https://micro.mamba.pm/install.sh)" && \
/openhands/micromamba/bin/micromamba config remove channels defaults && \
/openhands/micromamba/bin/micromamba config list && \
chown -R openhands:openhands /openhands/micromamba && \
chown -R cbutkus:cbutkus /openhands/micromamba && \
# Create read-only shared access to micromamba for all users
# This allows both root and openhands users to access the same packages
# while maintaining security by keeping openhands as the owner
@@ -290,12 +290,12 @@ RUN \
if [ -d /openhands/code ]; then rm -rf /openhands/code; fi && \
mkdir -p /openhands/code/openhands && \
touch /openhands/code/openhands/__init__.py && \
chown -R openhands:openhands /openhands/code && \
chown -R cbutkus:cbutkus /openhands/code && \
# Set global git configuration to ensure proper author/committer information
git config --global user.name "openhands" && \
git config --global user.email "openhands@all-hands.dev"
COPY --chown=openhands:openhands ./code/pyproject.toml ./code/poetry.lock /openhands/code/
COPY --chown=cbutkus:cbutkus ./code/pyproject.toml ./code/poetry.lock /openhands/code/
{{ install_dependencies_user() }}
{{ install_dependencies_root() }}
@@ -309,20 +309,20 @@ COPY --chown=openhands:openhands ./code/pyproject.toml ./code/poetry.lock /openh
USER root
RUN \
# Ensure group exists (prefer GID 1000 if available)
if ! getent group openhands >/dev/null 2>&1; then \
if getent group 1000 >/dev/null 2>&1; then groupadd openhands; else groupadd -g 1000 openhands; fi; \
if ! getent group cbutkus >/dev/null 2>&1; then \
if getent group 1000 >/dev/null 2>&1; then groupadd cbutkus; else groupadd -g 1000 cbutkus; fi; \
fi && \
# Ensure user exists (prefer UID 1000 if available)
if ! id -u openhands >/dev/null 2>&1; then \
if getent passwd 1000 >/dev/null 2>&1; then useradd -m -s /bin/bash -g openhands openhands; else useradd -u 1000 -g openhands -m -s /bin/bash openhands; fi; \
if ! id -u cbutkus >/dev/null 2>&1; then \
if getent passwd 1000 >/dev/null 2>&1; then useradd -m -s /bin/bash -g cbutkus cbutkus; else useradd -u 1000 -g cbutkus -m -s /bin/bash cbutkus; fi; \
fi && \
# Ensure home and required directories exist before later steps
mkdir -p /home/openhands && \
mkdir -p /home/cbutkus && \
mkdir -p /openhands && \
mkdir -p $(dirname ${OPENVSCODE_SERVER_ROOT}) && \
# Ensure ownership is correct for all OpenHands paths
chown -R openhands:openhands /home/openhands || true && \
chown -R openhands:openhands /openhands || true
chown -R cbutkus:cbutkus /home/cbutkus || true && \
chown -R cbutkus:cbutkus /openhands || true
{{ setup_vscode_server() }}
@@ -330,12 +330,12 @@ RUN \
# Copy Project source files
# ================================================================
RUN if [ -d /openhands/code/openhands ]; then rm -rf /openhands/code/openhands; fi
COPY --chown=openhands:openhands ./code/pyproject.toml ./code/poetry.lock /openhands/code/
COPY --chown=cbutkus:cbutkus ./code/pyproject.toml ./code/poetry.lock /openhands/code/
RUN if [ -d /openhands/code/microagents ]; then rm -rf /openhands/code/microagents; fi
COPY --chown=openhands:openhands ./code/microagents /openhands/code/microagents
COPY --chown=openhands:openhands ./code/openhands /openhands/code/openhands
COPY --chown=cbutkus:cbutkus ./code/microagents /openhands/code/microagents
COPY --chown=cbutkus:cbutkus ./code/openhands /openhands/code/openhands
RUN chmod a+rwx /openhands/code/openhands/__init__.py && \
chown -R openhands:openhands /openhands/code
chown -R cbutkus:cbutkus /openhands/code
# ================================================================
@@ -349,7 +349,7 @@ RUN chmod a+rwx /openhands/code/openhands/__init__.py && \
# Install extra dependencies if specified (as openhands user)
{% if extra_deps %}
USER openhands
USER cbutkus
RUN {{ extra_deps }}
{% endif %}
@@ -357,8 +357,8 @@ RUN {{ extra_deps }}
USER root
RUN \
# Set up environment for openhands user
echo 'export PATH="/usr/bin:/bin:/usr/sbin:/sbin:/openhands/micromamba/bin:$PATH"' >> /home/openhands/.bashrc && \
echo 'export PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers' >> /home/openhands/.bashrc && \
echo 'eval "$(/openhands/micromamba/bin/micromamba shell hook --shell bash)"' >> /home/openhands/.bashrc && \
echo 'micromamba activate openhands 2>/dev/null || true' >> /home/openhands/.bashrc && \
chown openhands:openhands /home/openhands/.bashrc
echo 'export PATH="/usr/bin:/bin:/usr/sbin:/sbin:/openhands/micromamba/bin:$PATH"' >> /home/cbutkus/.bashrc && \
echo 'export PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers' >> /home/cbutkus/.bashrc && \
echo 'eval "$(/openhands/micromamba/bin/micromamba shell hook --shell bash)"' >> /home/cbutkus/.bashrc && \
echo 'micromamba activate openhands 2>/dev/null || true' >> /home/cbutkus/.bashrc && \
chown cbutkus:cbutkus /home/cbutkus/.bashrc

View File

@@ -75,6 +75,7 @@ def create_conversation_validator() -> ConversationValidator:
'OPENHANDS_CONVERSATION_VALIDATOR_CLS',
'openhands.storage.conversation.conversation_validator.ConversationValidator',
)
logger.info(f'conversation_validator_cls is {conversation_validator_cls}')
ConversationValidatorImpl = get_impl(
ConversationValidator, conversation_validator_cls
)