diff --git a/code.sh b/code.sh index 9bd39d0..979ffef 100755 --- a/code.sh +++ b/code.sh @@ -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 '. 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 @@ -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" diff --git a/tests/default-mock.sh b/tests/default-mock.sh index 6df88ba..68c80d0 100644 --- a/tests/default-mock.sh +++ b/tests/default-mock.sh @@ -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 diff --git a/tests/framework/run-one-test.sh b/tests/framework/run-one-test.sh index 7313e01..7147937 100755 --- a/tests/framework/run-one-test.sh +++ b/tests/framework/run-one-test.sh @@ -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 @@ -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 diff --git a/tests/test-basic.sh b/tests/test-basic.sh index 6709f5b..a5933f5 100644 --- a/tests/test-basic.sh +++ b/tests/test-basic.sh @@ -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 @@ -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 @@ -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 diff --git a/tests/test-server-dir.sh b/tests/test-server-dir.sh new file mode 100644 index 0000000..ba9f205 --- /dev/null +++ b/tests/test-server-dir.sh @@ -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=&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 +} +