Skip to content

Commit 172f611

Browse files
authored
Merge pull request #3 from esi-neuroscience/dev
Setup Overhaul
2 parents bafe7bb + a8a946b commit 172f611

File tree

2 files changed

+201
-89
lines changed

2 files changed

+201
-89
lines changed

client/setup.ps1

+80-51
Original file line numberDiff line numberDiff line change
@@ -24,76 +24,91 @@ $sshconfig = "$sshdir\config"
2424
$sshconfigbak = "${sshconfig}_$(get-date -f yyyy-MM-dd).vsr"
2525
$sshkey = "$sshdir\$sshkeyname"
2626

27-
Write-Output "--- This script sets up VS Code remote connections to the HPC cluster ---"
27+
# Helpers to prettify output
28+
function ErrorMsg($msg) { Write-Host "FAILED: $msg" -ForegroundColor Red }
29+
function Announce($msg) { Write-Host ">>> $msg <<<" -ForegroundColor Green }
30+
function Info($msg) { Write-Host "$msg" -ForegroundColor Cyan }
31+
32+
# Helper to undo any changes made to the user's machine
33+
function Cleanup {
34+
if (Test-Path $sshconfig) {
35+
Copy-Item -Path "$sshconfig" -Destination "$sshconfigbak" -Force
36+
Info "Wrote backup-copy $sshconfigbak of current ssh configuration file"
37+
$lines = Get-Content $sshconfig
38+
$newLines = @()
39+
$skipBlock = $false
40+
foreach ($line in $lines) {
41+
# Detect start of block
42+
if ($line -match '^\s*Host\s+vscode-remote-hpc\s*$') {
43+
$skipBlock = $true
44+
continue
45+
}
46+
# If skipping block, skip indented lines; stop skipping on next non-indented/non-empty line
47+
if ($skipBlock) {
48+
if ($line -match '^\s' -or $line -match '^\t') {
49+
continue
50+
} elseif ($line -match '^\s*$') {
51+
continue # Skip empty lines directly after block, cosmetic
52+
} else {
53+
$skipBlock = $false
54+
# fall through and add this line, out of block
55+
}
56+
}
57+
if (-not $skipBlock) {
58+
$newLines += $line
59+
}
60+
}
61+
$newLines | Set-Content $sshconfig
62+
Info "Block for vscode-remote-hpc has been removed from $sshconfig (if it was present)."
63+
} else {
64+
Info "$sshconfig does not exist. Nothing to remove."
65+
}
66+
Info "Removing generated ssh key-pair"
67+
Remove-Item -Path "$sshkey" -Force -ErrorAction SilentlyContinue
68+
Remove-Item -Path "$sshkey.pub" -Force -ErrorAction SilentlyContinue
69+
Info "Done"
70+
}
71+
72+
# ----------------------------------------------------------------------
73+
# START OF INSTALLATION SCRIPT
74+
# ----------------------------------------------------------------------
75+
try {
76+
77+
Announce "This script sets up VS Code remote connections to the HPC cluster"
2878

2979
# Check if vscode-remote-hpc has already been setup
3080
if ((Test-Path $sshconfig) -and (Test-Path $sshkey)) {
3181
if ($PSBoundParameters.Count -eq 0) {
32-
Write-Output "It seems vscode-remote-hpc is already installed. How do you want to proceed?"
33-
Write-Output "1. Abort"
34-
Write-Output "2. Uninstall"
82+
Info "It seems vscode-remote-hpc is already installed. How do you want to proceed?"
83+
Info "1. Abort"
84+
Info "2. Uninstall"
3585
$choice = Read-Host "Please choose an option (1 or 2)"
3686
} else {
3787
$choice = '2'
3888
}
3989
switch ($choice) {
4090
'1' {
41-
exit
91+
return
4292
}
4393
'2' {
44-
Write-Output "Removing vscode-remote-hpc ssh configuration entry"
45-
if (Test-Path $sshconfig) {
46-
Copy-Item -Path "$sshconfig" -Destination "$sshconfigbak" -Force
47-
Write-Output "Wrote backup-copy $sshconfigbak of current ssh configuration file"
48-
$lines = Get-Content $sshconfig
49-
$newLines = @()
50-
$skipBlock = $false
51-
foreach ($line in $lines) {
52-
# Detect start of block
53-
if ($line -match '^\s*Host\s+vscode-remote-hpc\s*$') {
54-
$skipBlock = $true
55-
continue
56-
}
57-
# If skipping block, skip indented lines; stop skipping on next non-indented/non-empty line
58-
if ($skipBlock) {
59-
if ($line -match '^\s' -or $line -match '^\t') {
60-
continue
61-
} elseif ($line -match '^\s*$') {
62-
continue # Skip empty lines directly after block, cosmetic
63-
} else {
64-
$skipBlock = $false
65-
# fall through and add this line, out of block
66-
}
67-
}
68-
if (-not $skipBlock) {
69-
$newLines += $line
70-
}
71-
}
72-
$newLines | Set-Content $sshconfig
73-
Write-Output "Block for vscode-remote-hpc has been removed from $sshconfig (if it was present)."
74-
} else {
75-
Write-Output "$sshconfig does not exist. Nothing to remove."
76-
}
77-
Write-Output "Removing generated ssh key-pair"
78-
Remove-Item -Path "$sshkey" -Force -ErrorAction SilentlyContinue
79-
Remove-Item -Path "$sshkey.pub" -Force -ErrorAction SilentlyContinue
80-
Write-Output "Done"
81-
Write-Output "All cleaned up, vscode-remote-hpc has been uninstalled. Bye. "
94+
Cleanup
95+
Announce "All cleaned up, vscode-remote-hpc has been uninstalled. Bye."
8296
return
8397
}
8498
Default {
85-
Write-Output "Invalid choice. Aborting."
99+
ErrorMsg "Invalid choice. Aborting."
86100
return
87101
}
88102
}
89103
}
90104

91105
# Query account/head node information
92106
if (-not $uname) {
93-
$uname = Read-Host "Please enter your HPC uname: "
107+
Info "Please enter your HPC username:"
108+
$uname = Read-Host
94109
}
95110
if (-not $headnode) {
96-
Write-Output "Please enter the IP address or hostname of the cluster head node"
111+
Info "Please enter the IP address or hostname of the cluster head node"
97112
$headnode = Read-Host "(hub.esi.local at ESI, or 192.168.161.221 at CoBIC): "
98113
}
99114

@@ -122,22 +137,36 @@ if (-not (Test-Path -Path $sshconfig)) {
122137
$configText = Select-String -Path $sshconfig -Pattern "Host vscode-remote-hpc"
123138
if ($configText -eq $null){
124139
Add-Content -Path $sshconfig -Value "`n$configblock"
125-
Write-Output "Updated ssh configuration"
140+
Info "Updated ssh configuration"
126141
} else {
127-
Write-Output "VS Code remote HPC configuration already exists. No changes made."
142+
Info "VS Code remote HPC configuration already exists. No changes made."
128143
}
129144

130145
# If it does not exist already, create a new ssh key for vscode-remote-hpc
131146
if (-not (Test-Path -Path $sshkey)) {
132147
if ($PSBoundParameters.Count -eq 0) {
133-
$ans = Read-Host "About to create and upload an ssh key to $headnode. You will be prompted for your cluster password. Press any key to continue "
148+
Info "About to create and upload an ssh key to $headnode"
149+
Info "You will be prompted for your cluster password"
150+
$ans = Read-Host "Press any key to continue "
134151
}
135152
ssh-keygen -q -f $sshkey -t ed25519 -C "vscode-remote-hpc@${env:COMPUTERNAME}" -N '""'
153+
if (-not $?){
154+
throw "ssh-keygen failed"
155+
}
136156
if ($PSBoundParameters.Count -eq 0) {
137157
type "$sshkey.pub" | ssh $uname@$headnode "cat >> ~/.ssh/authorized_keys"
158+
if (-not $?){
159+
throw "ssh-key upload failed"
160+
}
138161
}
139162
} else {
140-
Write-Output "VS Code remote ssh key already exists. No changes made."
163+
Info "VS Code remote ssh key already exists. No changes made."
141164
}
142165

143-
Write-Output "-- All Done ---"
166+
Announce "All Done"
167+
168+
} catch {
169+
ErrorMsg "Setup encountered an error. Examine previous error messages for details"
170+
Cleanup
171+
return
172+
}

client/setup.sh

+121-38
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,28 @@
88
# SPDX-License-Identifier: MIT
99
#
1010

11+
set -e
12+
13+
# Keep it simple in case we're running in a POSIX-shell
14+
posix_abort() {
15+
printf "ERROR: %s\n" "$@" >&2
16+
exit 1
17+
}
18+
19+
# Fail fast with a concise message when not using bash
20+
# Single brackets are needed here for POSIX compatibility
21+
# shellcheck disable=SC2292
22+
if [ -z "${BASH_VERSION:-}" ]
23+
then
24+
posix_abort "Bash is required to interpret this script."
25+
fi
26+
27+
# Default ssh config/key location
28+
sshdir="${HOME}/.ssh"
29+
sshconfig="${sshdir}/config"
30+
sshconfigbak="${sshconfig}_$(date +%Y-%m-%d).vsr"
31+
sshkey="${sshdir}/vscode-remote-hpc"
32+
1133
# Either query for HPC username and headnode or take CLI arguments
1234
# (mainly intended for testing!)
1335
if [ -n "$1" ]; then
@@ -17,20 +39,96 @@ if [ -n "$2" ]; then
1739
headnode="$2"
1840
fi
1941

20-
# Default ssh config/key location
21-
sshdir="${HOME}/.ssh"
22-
sshconfig="${sshdir}/config"
23-
sshconfigbak="${sshconfig}_$(date +%Y-%m-%d).vsr"
24-
sshkey="${sshdir}/vscode-remote-hpc"
42+
# String formatters to prettify output
43+
if [[ -t 1 ]]; then
44+
tty_escape() { printf "\033[%sm" "$1"; }
45+
else
46+
tty_escape() { :; }
47+
fi
48+
tty_mkbold() { tty_escape "1;$1"; }
49+
tty_blue="$(tty_mkbold 34)"
50+
tty_green="$(tty_mkbold 32)"
51+
tty_red="$(tty_mkbold 31)"
52+
tty_bold="$(tty_mkbold 39)"
53+
tty_reset="$(tty_escape 0)"
54+
55+
shell_join()
56+
{
57+
local arg
58+
printf "%s" "$1"
59+
shift
60+
for arg in "$@"
61+
do
62+
printf " "
63+
printf "%s" "${arg// /\ }"
64+
done
65+
}
66+
67+
chomp()
68+
{
69+
printf "%s" "${1/"$'\n'"/}"
70+
}
71+
72+
announce()
73+
{
74+
printf "${tty_green}>>> %s <<<${tty_reset}\n" "$(shell_join "$@")"
75+
}
76+
77+
info()
78+
{
79+
printf "${tty_blue}%s${tty_reset}\n" "$(shell_join "$@")"
80+
}
81+
82+
error()
83+
{
84+
printf "${tty_red}FAILED:${tty_bold} %s${tty_reset}\n" "$(chomp "$1")"
85+
}
86+
87+
# Ensure errors are communicated properly
88+
on_exit() {
89+
if [ $? -ne 0 ]; then
90+
error "Setup encountered an error. Examine previous error messages for details"
91+
cleanup
92+
exit 1
93+
fi
94+
info "Bye"
95+
}
96+
trap 'on_exit 2> /dev/null' SIGHUP SIGTERM SIGKILL EXIT
97+
98+
# Helper to undo any changes made to the user's machine
99+
cleanup(){
100+
if [[ -f "${sshconfig}" ]]; then
101+
cp -f "${sshconfig}" "${sshconfigbak}"
102+
info "Wrote backup-copy ${sshconfigbak} of current ssh configuration file"
103+
awk '
104+
BEGIN {skip=0}
105+
/^[ \t]*Host[ \t]+vscode-remote-hpc[ \t]*$/ {skip=1; next}
106+
skip && /^[ \t]/ {next}
107+
skip && /^[[:space:]]*$/ {next}
108+
skip {skip=0}
109+
{print}
110+
' "${sshconfig}" > "${sshconfig}.tmp" && mv "${sshconfig}.tmp" "${sshconfig}"
111+
info "Block for vscode-remote-hpc has been removed from ${sshconfig} (if it was present)."
112+
else
113+
info "${sshconfig} does not exist. Nothing to remove."
114+
fi
115+
info "Removing generated ssh key-pair"
116+
rm -f "${sshkey}"
117+
rm -f "${sshkey}.pub"
118+
info "Done"
119+
}
25120

26-
echo "--- This script sets up VS Code remote connections to the HPC cluster ---"
121+
# ----------------------------------------------------------------------
122+
# START OF INSTALLATION SCRIPT
123+
# ----------------------------------------------------------------------
124+
announce "This script sets up VS Code remote connections to the HPC cluster"
27125

28126
# Check if vscode-remote-hpc has already been setup
29127
if [[ -f "${sshconfig}" && -f "${sshkey}" ]]; then
30128
if [[ $# -eq 0 ]]; then
31-
echo "It seems vscode-remote-hpc is already installed. How do you want to proceed?"
32-
echo "1. Abort"
33-
echo "2. Uninstall"
129+
info "It seems vscode-remote-hpc is already installed. How do you want to proceed?"
130+
info "1. Abort"
131+
info "2. Uninstall"
34132
read -p "Please choose an option (1 or 2): " choice </dev/tty
35133
else
36134
choice='2'
@@ -40,42 +138,25 @@ if [[ -f "${sshconfig}" && -f "${sshkey}" ]]; then
40138
exit
41139
;;
42140
2)
43-
if [[ -f "${sshconfig}" ]]; then
44-
cp -f "${sshconfig}" "${sshconfigbak}"
45-
echo "Wrote backup-copy ${sshconfigbak} of current ssh configuration file"
46-
awk '
47-
BEGIN {skip=0}
48-
/^[ \t]*Host[ \t]+vscode-remote-hpc[ \t]*$/ {skip=1; next}
49-
skip && /^[ \t]/ {next}
50-
skip && /^[[:space:]]*$/ {next}
51-
skip {skip=0}
52-
{print}
53-
' "${sshconfig}" > "${sshconfig}.tmp" && mv "${sshconfig}.tmp" "${sshconfig}"
54-
echo "Block for vscode-remote-hpc has been removed from ${sshconfig} (if it was present)."
55-
else
56-
echo "${sshconfig} does not exist. Nothing to remove."
57-
fi
58-
echo "Removing generated ssh key-pair"
59-
rm -f "${sshkey}"
60-
rm -f "${sshkey}.pub"
61-
echo "Done"
62-
echo "All cleaned up, vscode-remote-hpc has been uninstalled. Bye. "
141+
cleanup
142+
announce "All cleaned up, vscode-remote-hpc has been uninstalled."
63143
exit
64144
;;
65145
*)
66-
echo "Invalid choice. Aborting."
146+
error "Invalid choice. Aborting."
67147
exit
68148
;;
69149
esac
70150
fi
71151

72152
# Query account/head node information
73153
if [[ -z "${uname+x}" ]]; then
74-
read -p "Please enter your HPC username: " uname </dev/tty
154+
info "Please enter your HPC username:"
155+
read -p "" uname </dev/tty
75156
fi
76157
if [[ -z "${headnode+x}" ]]; then
77-
echo "Please enter the IP address or hostname of the cluster head node"
78-
read -p " (hub.esi.local at ESI, or 192.168.161.221 at CoBIC): " headnode </dev/tty
158+
info "Please enter the IP address or hostname of the cluster head node"
159+
read -p "(hub.esi.local at ESI, or 192.168.161.221 at CoBIC): " headnode </dev/tty
79160
fi
80161

81162
# Put together configuration block for ssh config
@@ -104,15 +185,17 @@ fi
104185
if ! grep -qE '^[Hh]ost[[:space:]]+vscode-remote-hpc\b' "${sshconfig}"; then
105186
echo "" >> "${sshconfig}"
106187
echo "${configblock}" >> "${sshconfig}"
107-
echo "Updated ssh configuration"
188+
info "Updated ssh configuration"
108189
else
109-
echo "VS Code remote HPC configuration already exists. No changes made."
190+
info "VS Code remote HPC configuration already exists. No changes made."
110191
fi
111192

112193
# If it does not exist already, create a new ssh key for vscode-remote-hpc
113194
if [ ! -f "${sshkey}" ]; then
114195
if [[ $# -eq 0 ]]; then
115-
read -p "About to create and upload an ssh key to ${headnode}. You will be prompted for your cluster password. Press any key to continue " ans </dev/tty
196+
info "About to create and upload an ssh key to ${headnode}"
197+
info "You will be prompted for your cluster password"
198+
read -p "Press any key to continue " ans </dev/tty
116199
fi
117200
machine="${HOST}"
118201
if [ -z "${machine}" ]; then
@@ -123,7 +206,7 @@ if [ ! -f "${sshkey}" ]; then
123206
ssh-copy-id -i "${sshkey}" "${uname}@${headnode}"
124207
fi
125208
else
126-
echo "VS Code remote ssh key already exists. No changes made."
209+
info "VS Code remote ssh key already exists. No changes made."
127210
fi
128211

129-
echo "-- All Done ---"
212+
announce "All Done"

0 commit comments

Comments
 (0)