-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add conditions to the SSH agent post-start command #1338
Conversation
Hi @vinokurig. Thanks for your PR. I'm waiting for a devfile member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
@vinokurig Just to clarify: the intention of adding the timeout to the ssh-add is prevent the workspace from failing in the case where the user has provided an incorrect SSH passphrase? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vinokurig Thank you for your quick PR in fixing this issue. I still have to do further testing, but here are my current thoughts & suggestions:
- Maybe we should improve the formatting of the commands for clarity? Here's an idea of how this could look:
SSH_ENV_PATH=$HOME/ssh-environment && \
if [ -f /etc/ssh/passphrase ] && [ -w $HOME ] && command -v ssh-add >/dev/null; then
ssh-agent | sed 's/^echo/#echo/' > $SSH_ENV_PATH \
&& chmod 600 $SSH_ENV_PATH \
&& source $SSH_ENV_PATH \
&& if timeout 3 ssh-add /etc/ssh/dwo_ssh_key < /etc/ssh/passphrase && [ -f $HOME/.bashrc ] && [ -w $HOME/.bashrc ]; then
echo "source ${SSH_ENV_PATH}" >> $HOME/.bashrc
fi
fi
- We could also add some
else
statements to clarify which steps might have failed:
SSH_ENV_PATH=$HOME/ssh-environment && \
if [ -f /etc/ssh/passphrase ] && [ -w $HOME ] && command -v ssh-add >/dev/null; then
ssh-agent | sed 's/^echo/#echo/' > $SSH_ENV_PATH \
&& chmod 600 $SSH_ENV_PATH \
&& source $SSH_ENV_PATH \
&& if timeout 3 ssh-add /etc/ssh/dwo_ssh_key < /etc/ssh/passphrase; then
if [ -f $HOME/.bashrc ] && [ -w $HOME/.bashrc ]; then
echo "source ${SSH_ENV_PATH}" >> $HOME/.bashrc
else
echo "$HOME/.bashrc does not exist or is not writable."
fi
else
echo "Provided SSH passphrase is invalid"
fi
else
if [ ! -f /etc/ssh/passphrase ]; then
echo "/etc/ssh/passphrase file does not exist."
fi
if [ ! -w $HOME ]; then
echo "$HOME directory is not writable."
fi
if ! command -v ssh-add >/dev/null; then
echo "ssh-add command not found."
fi
fi
- We could wrap the entire command with a
(... || true)
as an added safety mechanism for commands that are unlikely to fail, but still could theoretically fail. For example, if thessh-agent
command is missing for some reason:
(
SSH_ENV_PATH=$HOME/ssh-environment && \
if [ -f /etc/ssh/passphrase ] && [ -w $HOME ] && command -v ssh-add >/dev/null; then
ssh-agent | sed 's/^echo/#echo/' > $SSH_ENV_PATH \
&& chmod 600 $SSH_ENV_PATH \
&& source $SSH_ENV_PATH \
&& if timeout 3 ssh-add /etc/ssh/dwo_ssh_key < /etc/ssh/passphrase; then
if [ -f $HOME/.bashrc ] && [ -w $HOME/.bashrc ]; then
echo "source ${SSH_ENV_PATH}" >> $HOME/.bashrc
else
echo "$HOME/.bashrc does not exist or is not writable."
fi
else
echo "Provided SSH passphrase is invalid"
fi
else
if [ ! -f /etc/ssh/passphrase ]; then
echo "/etc/ssh/passphrase file does not exist."
fi
if [ ! -w $HOME ]; then
echo "$HOME directory is not writable."
fi
if ! command -v ssh-add >/dev/null; then
echo "ssh-add command not found."
fi
fi
) || true
I realize with all these suggestions applied, the final command is extremely verbose (maybe overkill). A nice middle ground might be to apply some formatting and wrap the entire command in (... || true)
to ensure this postStart will never fail a workspace that uses a container image with sh
installed. For example:
(
SSH_ENV_PATH=$HOME/ssh-environment && \
if [ -f /etc/ssh/passphrase ] && [ -w $HOME ] && command -v ssh-add >/dev/null; then
ssh-agent | sed 's/^echo/#echo/' > $SSH_ENV_PATH \
&& chmod 600 $SSH_ENV_PATH \
&& source $SSH_ENV_PATH \
&& if timeout 3 ssh-add /etc/ssh/dwo_ssh_key < /etc/ssh/passphrase && [ -f $HOME/.bashrc ] && [ -w $HOME/.bashrc ]; then
echo "source ${SSH_ENV_PATH}" >> $HOME/.bashrc
fi
fi
) || true
When wrapping the entire command with (... || true)
, any uncaught errors that occur will be outputted to /tmp/poststart-stdout.txt
.
@vinokurig I tested out your PR and it works as expected :) kind: DevWorkspace
apiVersion: workspace.devfile.io/v1alpha2
metadata:
name: plain-go-toolset
spec:
started: true
routingClass: 'basic'
template:
components:
- name: web-terminal
container:
image: registry.access.redhat.com/ubi9/go-toolset:1.19.13-4.1697647145
memoryRequest: 256Mi
memoryLimit: 512Mi
mountSources: true
command:
- "tail"
- "-f"
- "/dev/null" |
/ok-to-test |
/retest-required |
pkg/library/ssh/event.go
Outdated
then ssh-agent | sed 's/^echo/#echo/' > $SSH_ENV_PATH \ | ||
&& chmod 600 $SSH_ENV_PATH && source $SSH_ENV_PATH \ | ||
&& ssh-add /etc/ssh/dwo_ssh_key < /etc/ssh/passphrase \ | ||
&& if [ -f $HOME/.bashrc ] && [ -w $HOME/.bashrc ]; then echo "source ${SSH_ENV_PATH}" >> $HOME/.bashrc; fi; fi` | ||
&& if timeout 3 ssh-add /etc/ssh/dwo_ssh_key < /etc/ssh/passphrase \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vinokurig could you clarify the timeout part, looks error prone
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ibuziuk This is need to skip the passphrase input in case if the stored passphrase is wrong. There are some elaborations in the pull request description.
yes |
@AObuchow Thank you for the review and for the proposals.
done
done |
/retest-required |
pkg/library/ssh/event.go
Outdated
&& chmod 600 $SSH_ENV_PATH && source $SSH_ENV_PATH \ | ||
&& ssh-add /etc/ssh/dwo_ssh_key < /etc/ssh/passphrase \ | ||
&& if [ -f $HOME/.bashrc ] && [ -w $HOME/.bashrc ]; then echo "source ${SSH_ENV_PATH}" >> $HOME/.bashrc; fi; fi` | ||
const commandLine = `(SSH_ENV_PATH=$HOME/ssh-environment \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me, but in my testing I was able to copy & paste my final suggestion, which did not include a \
for every line as well as ;
and had slightly different formatting that seemed a bit clearer to me:
const commandLine = `(
SSH_ENV_PATH=$HOME/ssh-environment && \
if [ -f /etc/ssh/passphrase ] && [ -w $HOME ] && command -v ssh-add >/dev/null; then
ssh-agent | sed 's/^echo/#echo/' > $SSH_ENV_PATH \
&& chmod 600 $SSH_ENV_PATH \
&& source $SSH_ENV_PATH \
&& if timeout 3 ssh-add /etc/ssh/dwo_ssh_key < /etc/ssh/passphrase && [ -f $HOME/.bashrc ] && [ -w $HOME/.bashrc ]; then
echo "source ${SSH_ENV_PATH}" >> $HOME/.bashrc
fi
fi
) || true`
WDYT? Do we really need the \
line breaks and the ;
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion, applied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW I added a new check for the ssh-agent
availability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thank you so much @vinokurig & good call on the check for the ssh-agent
command 👍
/test v14-devworkspace-operator-e2e |
Signed-off-by: ivinokur <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, great work & thank you for fixing this so quickly @vinokurig :)
In my testing, I tried the following devworkspace which also includes a succeeding and failing command, to ensure they would not be affected:
kind: DevWorkspace
apiVersion: workspace.devfile.io/v1alpha2
metadata:
name: plain-go-toolset-with-event
spec:
started: true
routingClass: 'basic'
template:
components:
- name: web-terminal
container:
image: registry.access.redhat.com/ubi9/go-toolset:1.19.13-4.1697647145
memoryRequest: 256Mi
memoryLimit: 512Mi
mountSources: true
command:
- "tail"
- "-f"
- "/dev/null"
commands:
- id: say-hello
exec:
component: web-terminal
commandLine: echo "Hello from $(pwd)"
workingDir: /
- id: invalid
exec:
component: web-terminal
commandLine: invalid-command
workingDir: /
events:
postStart:
- say-hello
- invalid
The resulting postStart lifecycle hook in the pod:
lifecycle:
postStart:
exec:
command:
- /bin/sh
- -c
- |
{
cd /
echo "Hello from $(pwd)"
cd /
invalid-command
(
SSH_ENV_PATH=$HOME/ssh-environment && \
if [ -f /etc/ssh/passphrase ] && [ -w $HOME ] && command -v ssh-add >/dev/null && command -v ssh-agent >/dev/null; then
ssh-agent | sed 's/^echo/#echo/' > $SSH_ENV_PATH \
&& chmod 600 $SSH_ENV_PATH \
&& source $SSH_ENV_PATH \
&& if timeout 3 ssh-add /etc/ssh/dwo_ssh_key < /etc/ssh/passphrase && [ -f $HOME/.bashrc ] && [ -w $HOME/.bashrc ]; then
echo "source ${SSH_ENV_PATH}" >> $HOME/.bashrc
fi
fi
) || true
} 1>/tmp/poststart-stdout.txt 2>/tmp/poststart-stderr.txt
I saw that the valid command had it's stdout logged, and the invalid command had stderr logged correctly:
bash-5.1$ cat /tmp/poststart-stderr.txt
/bin/sh: line 5: invalid-command: command not found
bash-5.1$ cat /tmp/poststart-stdout.txt
Hello from /
@dkwon17 when you get a chance, could you please take a look at this PR? |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: AObuchow, dkwon17, vinokurig The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Great work @vinokurig & thank you for reviewing this @dkwon17 -- merging :) |
What does this PR do?
Add extra conditions to the SSH agent post-start command:
$HOME
directory for the write permissions in order to create thessh-environment
file in the user home directory.timeout
to thessh-add <key path> < <passphrase path>
command. If the passphrase is incorrect, then thessh-add
asks to input a new password:The command will stuck to wait the user input, but the timeout will interrupt the command.
What issues does this PR fix or reference?
fixes #1337 eclipse-che/che#23213
Is it tested? How?
see #1337
PR Checklist
/test v8-devworkspace-operator-e2e, v8-che-happy-path
to trigger)v8-devworkspace-operator-e2e
: DevWorkspace e2e testv8-che-happy-path
: Happy path for verification integration with Che