Skip to content

Commit

Permalink
Handle when $HOME for the container is not /root
Browse files Browse the repository at this point in the history
Visual Studio Code uses HOME from the container config to determine
where it puts .vscode-server. Toolboxes created with older versions of
toolbox+podman have HOME=/root, but with newer versions, we might end up with
HOME=/var/home/<user> or HOME=/.

Handle all these cases. In particular for the user-home-directory case,
put a symlink from /var/home/<user>/.vscode-server => /.vscode-server
to make sure that the configuration is properly per-container.
  • Loading branch information
owtaylor committed Mar 22, 2021
1 parent 74eb28b commit b21a35f
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 9 deletions.
64 changes: 55 additions & 9 deletions code.sh
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,60 @@ elif ! grep -q '"remote\.containers\.dockerPath": *"'"$wrapper_quoted"'"' "$sett
fi
fi

### Make sure that we have a writeable-by-user /root/.vscode-server directory

# this is where vscode stores per-container data/settings
if [ ! -w /root/.vscode-server ] ; then
info "Creating /root/.vscode-server"
sudo chmod a+x /root
sudo mkdir -p /root/.vscode-server
sudo chown $UID:"$(id -g)" /root/.vscode-server
### See where VSCode is going to write machine specific config/data

# VSCode puts its .vscode-server directory in the value of $HOME
# determined by 'podman inspect <container>'. For toolboxes, three
# values have been seen, depending on podman version.
#
# /root
# /
# User's homedir
#
# The first two are OK - we just need to make them world-writable,
# but for the third, we need ot create a symlink to avoid having
# different toolboxes step on each other.

homevar="$(flatpak-spawn --host podman inspect "$container_name" \
--format='{{ range .Config.Env }}{{ . }}{{"\n"}}{{ end }}' \
| grep ^HOME=)"
homevar="${homevar#HOME=}"

case $homevar in
/)
vscode_server="/.vscode-server"
;;
/root)
vscode_server="/root/.vscode-server"
;;
"$HOME")
vscode_server="/.vscode-server"

if [ -e "$HOME/.vscode-server" ] && [ ! -L "$HOME/.vscode-server" ] ; then
echo "$HOME/.vscode-server is not a symlink - this is probably a left-over." 1>&2
echo "Please delete this directory and re-run." 1>&2
exit 1
fi
if [ "$(readlink "$HOME/.vscode-server")" != $vscode_server ] ; then
info "Creating symlink from $HOME/.vscode-server to /.vscode-server"
ln -T -sf $vscode_server "$HOME/.vscode-server"
fi
;;
*)
echo "\$HOME in container config is: '$homevar' - don't know how to handle this." 1>&2
exit 1
;;
esac

### Make sure that we have a writeable-by-user .vscode-server directory

if [ ! -w $vscode_server ] ; then
info "Creating $vscode_server"
if [ $vscode_server = /root/.vscode-server ] ; then
sudo chmod a+x /root
fi
sudo mkdir -p $vscode_server
sudo chown $UID:"$(id -g)" $vscode_server
fi

### Make sure we have a visual-studio code configuration for this container
Expand Down Expand Up @@ -324,7 +370,7 @@ fi
# but if the user adds any settings for the container, the settings-key in the
# attached-container configuration file is overwritten without merging.

settings="/root/.vscode-server/data/Machine/settings.json"
settings="$vscode_server/data/Machine/settings.json"
if $toolbox_reset_configuration || [ ! -f $settings ] ; then
info "Creating $settings"

Expand Down
6 changes: 6 additions & 0 deletions tests/default-mock.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ if match flatpak install flathub com.visualstudio.code ; then
exit 0
fi

if match podman inspect toolbox-vscode-test \
--format='{{ range .Config.Env }}{{ . }}{{"\n"}}{{ end }}' ; then
echo "NAME=fedora-toolbox"
echo "HOME=/root"
fi

if match flatpak ps --columns=instance,application ; then
exit 0
fi
Expand Down
11 changes: 11 additions & 0 deletions tests/framework/run-one-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ ln -s /source/tests/framework/mock-flatpak-spawn.sh $bindir/flatpak-spawn

### Functions for tests

fail() {
echo "$*" 1>&2
exit 1
}

assert_contents() {
cat > /logs/expected
if ! cmp -s /logs/expected "$1" ; then
Expand All @@ -41,6 +46,12 @@ assert_contents() {
fi
}

assert_grep() {
if ! grep -q "$1" "$2" ; then
fail "Failed to find '$1' in '$2'"
fi
}

### Run the test

# shellcheck disable=SC1090
Expand Down
3 changes: 3 additions & 0 deletions tests/test-basic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ test_basic() {

assert_contents /logs/basic.cmd <<'EOF'
flatpak list --app --columns=application
podman inspect toolbox-vscode-test --format={{ range .Config.Env }}{{ . }}{{"\n"}}{{ end }}
flatpak ps --columns=instance,application
flatpak run com.visualstudio.code --remote attached-container+746f6f6c626f782d7673636f64652d74657374 /home/testuser/project
EOF
Expand Down Expand Up @@ -76,6 +77,7 @@ test_installation() {
flatpak list --app --columns=application
flatpak remotes --columns=name
flatpak install flathub com.visualstudio.code
podman inspect toolbox-vscode-test --format={{ range .Config.Env }}{{ . }}{{"\n"}}{{ end }}
flatpak ps --columns=instance,application
flatpak run com.visualstudio.code --remote attached-container+746f6f6c626f782d7673636f64652d74657374 /home/testuser/project
EOF
Expand All @@ -95,6 +97,7 @@ test_running() {

assert_contents /logs/running.cmd <<'EOF'
flatpak list --app --columns=application
podman inspect toolbox-vscode-test --format={{ range .Config.Env }}{{ . }}{{"\n"}}{{ end }}
flatpak ps --columns=instance,application
flatpak enter 123456 sh -c
cd $0
Expand Down
101 changes: 101 additions & 0 deletions tests/test-server-dir.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Different versions of toolbox+podman result in different values of the HOME
# environment variable in the container config. Since that determines the
# location where Visual Studio Code puts the '.vscode-server' directory,
# we have to handle them all.

# shellcheck shell=bash

do_mock_server_dir() {
if match podman inspect toolbox-vscode-test \
--format='{{ range .Config.Env }}{{ . }}{{"\n"}}{{ end }}' ; then
echo "NAME=fedora-toolbox"
echo "HOME=$1"
exit 1
fi
}

### HOME=/

mock_server_dir_topdir() {
do_mock_server_dir /
}

test_server_dir_topdir() {
code .
assert_grep '"remote.containers.copyGitConfig": false' \
/.vscode-server/data/Machine/settings.json
}

### HOME=/root

mock_server_dir_root() {
do_mock_server_dir /root
}

test_server_dir_root() {
code .
assert_grep '"remote.containers.copyGitConfig": false' \
/root/.vscode-server/data/Machine/settings.json
}

### HOME=/home/testuser

check_home_symlink() {
if [ ! -L /home/testuser/.vscode-server ] || \
[ "$(readlink /home/testuser/.vscode-server)" != "/.vscode-server" ] ; then
fail "Link to /.vscode/server wasn't created succesfully"
fi
}

mock_server_dir_home() {
do_mock_server_dir /home/testuser
}

test_server_dir_home() {
code .
check_home_symlink
assert_grep '"remote.containers.copyGitConfig": false' \
/home/testuser/.vscode-server/data/Machine/settings.json
}

### HOME=/home/testuser, symlink at ~/.vscode-server points somewhere else

mock_server_dir_home_old_symlink() {
do_mock_server_dir /home/testuser
}

test_server_dir_home_old_symlink() {
ln -s /bah/bah /home/testuser/.vscode-server
code .
check_home_symlink
assert_grep '"remote.containers.copyGitConfig": false' \
/home/testuser/.vscode-server/data/Machine/settings.json
}

### HOME=/home/testuser, ~/.vscode-server exists and isn't a symlink

mock_server_dir_home_old_dir() {
do_mock_server_dir /home/testuser
}

test_server_dir_home_old_dir() {
mkdir /home/testuser/.vscode-server
code . 2>&1 | tee /logs/server_dir_home_old_dir.stdout
[[ ${PIPESTATUS[0]} = 1 ]] || fail "Should have exited unsuccessfully"
assert_grep "$HOME/.vscode-server is not a symlink - this is probably a left-over." \
/logs/server_dir_home_old_dir.stdout
}

### HOME=<somehwere else

mock_server_dir_unknown() {
do_mock_server_dir /home/otheruser
}

test_server_dir_unknown() {
code . 2>&1 | tee /logs/server_dir_unknown.stdout
[[ ${PIPESTATUS[0]} = 1 ]] || fail "Should have exited unsuccessfully"
assert_grep "\$HOME in container config is: '/home/otheruser' - don't know how to handle this." \
/logs/server_dir_unknown.stdout
}

0 comments on commit b21a35f

Please sign in to comment.