Skip to content

Commit

Permalink
fixup! Add a poststart event to initialise ssh-agent if needed
Browse files Browse the repository at this point in the history
Signed-off-by: ivinokur <ivinokur@redhat.com>
  • Loading branch information
vinokurig committed Aug 19, 2024
1 parent e565563 commit 6a6cd5e
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 29 deletions.
5 changes: 5 additions & 0 deletions controllers/workspace/devworkspace_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,11 @@ func (r *DevWorkspaceReconciler) Reconcile(ctx context.Context, req ctrl.Request
return r.failWorkspace(workspace, fmt.Sprintf("Failed to mount ServiceAccount tokens to workspace: %s", err), metrics.ReasonBadRequest, reqLogger, &reconcileStatus), nil
}

// Add SSH ask-pass script into devfile containers
if err := wsprovision.ProvisionSshSshAskPass(clusterAPI, workspace.Namespace, devfilePodAdditions); err != nil {
return r.failWorkspace(workspace, fmt.Sprintf("Failed to mount SSH askpass script to workspace: %s", err), metrics.ReasonBadRequest, reqLogger, &reconcileStatus), nil
}

// Add automount resources into devfile containers
err = automount.ProvisionAutoMountResourcesInto(devfilePodAdditions, clusterAPI, workspace.Namespace, home.PersistUserHomeEnabled(workspace))
if shouldReturn, reconcileResult, reconcileErr := r.checkDWError(workspace, err, "Failed to process automount resources", metrics.ReasonBadRequest, reqLogger, &reconcileStatus); shouldReturn {
Expand Down
23 changes: 15 additions & 8 deletions pkg/library/env/workspaceenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"fmt"
"os"

"github.com/devfile/devworkspace-operator/pkg/provision/automount"
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"

dw "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/devworkspace-operator/apis/controller/v1alpha1"
Expand Down Expand Up @@ -82,20 +82,27 @@ func commonEnvironmentVariables(workspaceWithConfig *common.DevWorkspaceWithConf
Name: constants.DevWorkspaceIdleTimeout,
Value: workspaceWithConfig.Config.Workspace.IdleTimeout,
},
{
Name: constants.DISPLAY,
Value: ":0",
}, {
Name: constants.SSHAskPass,
Value: automount.SshAskPassMountPath + automount.SshAskPassScriptFileName,
},
}

envvars = append(envvars, GetProxyEnvVars(workspaceWithConfig.Config.Routing.ProxyConfig)...)
envvars = append(envvars, GetSshAskPassEnvVars()...)

return envvars
}

func GetSshAskPassEnvVars() []corev1.EnvVar {
return []corev1.EnvVar{
{
Name: constants.SSHAskPass,
Value: fmt.Sprintf("%s%s", workspace.SshAskPassMountPath, workspace.SshAskPassScriptFileName),
},
{
Name: constants.DISPLAY,
Value: ":0",
},
}
}

func GetProxyEnvVars(proxyConfig *v1alpha1.Proxy) []corev1.EnvVar {
if proxyConfig == nil {
return nil
Expand Down
4 changes: 2 additions & 2 deletions pkg/library/ssh/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ func AddSshAgentPostStartEvent(spec *v1alpha2.DevWorkspaceTemplateSpec) error {
&& if [ -f /etc/ssh/passphrase ] && command -v ssh-add >/dev/null; \
then ssh-agent | sed 's/^echo/#echo/' > $SSH_ENV_PATH \
&& chmod 600 $SSH_ENV_PATH && . $SSH_ENV_PATH \
&& ssh-add /etc/ssh/dwo_ssh_key < /etc/ssh/passphrase \
&& echo ". ${SSH_ENV_PATH}" >> /home/user/.bashrc; fi`
&& ssh-add /etc/ssh/dwo_ssh_key < /etc/ssh/passphrase; fi \
&& if [ -f /home/user/.bashrc ]; then echo ". ${SSH_ENV_PATH}" >> /home/user/.bashrc; fi`
_, mainComponents, err := lifecycle.GetInitContainers(spec.DevWorkspaceTemplateSpecContent)
for _, component := range mainComponents {
if component.Container == nil {
Expand Down
7 changes: 1 addition & 6 deletions pkg/provision/automount/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,7 @@ func getAutomountResources(api sync.ClusterAPI, namespace string) (*Resources, e
return nil, err
}

sshCMAutoMountResources, err := ProvisionSshAskPassScript(api, namespace)
if err != nil {
return nil, err
}

return mergeAutomountResources(gitCMAutoMountResources, mergedResources, pvcAutoMountResources, sshCMAutoMountResources), nil
return mergeAutomountResources(gitCMAutoMountResources, mergedResources, pvcAutoMountResources), nil
}

func checkAutomountVolumesForCollision(podAdditions *v1alpha1.PodAdditions, automount *Resources) error {
Expand Down
2 changes: 1 addition & 1 deletion pkg/provision/automount/common_persistenthome_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestProvisionAutomountResourcesIntoPersistentHomeEnabled(t *testing.T) {

err := ProvisionAutoMountResourcesInto(podAdditions, testAPI, testNamespace, true)

if assert.ErrorContains(t, err, "Created object") || !assert.NoError(t, err, "Unexpected error") {
if !assert.NoError(t, err, "Unexpected error") {
return
}
assert.Truef(t, cmp.Equal(tt.Output.Volumes, podAdditions.Volumes, testDiffOpts),
Expand Down
File renamed without changes.
46 changes: 39 additions & 7 deletions pkg/provision/automount/ssh.go → pkg/provision/workspace/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
// limitations under the License.
//

package automount
package workspace

import (
_ "embed"
"path"

"github.com/devfile/devworkspace-operator/apis/controller/v1alpha1"
"github.com/devfile/devworkspace-operator/pkg/constants"
"github.com/devfile/devworkspace-operator/pkg/dwerrors"
"github.com/devfile/devworkspace-operator/pkg/provision/sync"
Expand All @@ -32,15 +34,23 @@ const SshAskPassScriptFileName = "ssh-askpass.sh"
//go:embed ssh-askpass.sh
var data string

func ProvisionSshAskPassScript(api sync.ClusterAPI, namespace string) (*Resources, error) {
func ProvisionSshSshAskPass(api sync.ClusterAPI, namespace string, podAdditions *v1alpha1.PodAdditions) error {
sshAskPassConfigMap := constructSshAskPassCM(namespace)
if _, err := sync.SyncObjectWithCluster(sshAskPassConfigMap, api); err != nil {
return nil, dwerrors.WrapSyncError(err)
switch err.(type) {
case *sync.NotInSyncError: // Ignore the object created error
default:
return dwerrors.WrapSyncError(err)
}
}
resources := flattenAutomountResources([]Resources{
getAutomountConfigmap(SshAskPassMountPath, constants.DevWorkspaceMountAsSubpath, pointer.Int32(0755), sshAskPassConfigMap),
})
return &resources, nil

sshAskPassVolumeMounts, sshAskPassVolumes, err := getSshAskPassVolumesAndVolumeMounts()
if err != nil {
return err
}
podAdditions.VolumeMounts = append(podAdditions.VolumeMounts, sshAskPassVolumeMounts...)
podAdditions.Volumes = append(podAdditions.Volumes, sshAskPassVolumes...)
return nil
}

func constructSshAskPassCM(namespace string) *corev1.ConfigMap {
Expand All @@ -60,3 +70,25 @@ func constructSshAskPassCM(namespace string) *corev1.ConfigMap {
}
return askPassConfigMap
}

func getSshAskPassVolumesAndVolumeMounts() ([]corev1.VolumeMount, []corev1.Volume, error) {
name := "ssh-askpass"
volume := corev1.Volume{
Name: name,
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: constants.SshAskPassConfigMapName,
},
DefaultMode: pointer.Int32(0755),
},
},
}
volumeMount := corev1.VolumeMount{
Name: name,
ReadOnly: true,
MountPath: path.Join(SshAskPassMountPath, SshAskPassScriptFileName),
SubPath: SshAskPassScriptFileName,
}
return []corev1.VolumeMount{volumeMount}, []corev1.Volume{volume}, nil
}
6 changes: 1 addition & 5 deletions project-clone/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,10 @@ COPY --from=builder /project-clone/_output/bin/project-clone /usr/local/bin/proj

ENV USER_UID=1001 \
USER_NAME=project-clone \
HOME=/home/user \
DISPLAY=":0" \
SSH_ASKPASS=/usr/local/bin/ssh-askpass.sh
HOME=/home/user

COPY build/bin /usr/local/bin
COPY pkg/provision/automount/ssh-askpass.sh /usr/local/bin
RUN /usr/local/bin/user_setup
RUN chmod +x /usr/local/bin/ssh-askpass.sh

USER ${USER_UID}

Expand Down

0 comments on commit 6a6cd5e

Please sign in to comment.