Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion api/v1alpha1/workspace_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,39 @@ type WorkspaceFile struct {
Content string `json:"content"`
}

// SetupContainer defines an init container that runs after git clone but
// before the agent container starts. Setup containers receive the workspace
// volume mount (at /workspace) and any user-defined workspace volumes.
type SetupContainer struct {
// Name is the init container name (must be unique across setup containers).
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`

// Image is the container image to run.
// +kubebuilder:validation:MinLength=1
Image string `json:"image"`

// Command is the entrypoint array (passed to the container as the command).
// +kubebuilder:validation:MinItems=1
Command []string `json:"command"`

// Env are additional environment variables for the container.
// +optional
Env []EnvVar `json:"env,omitempty"`
}

// EnvVar represents an environment variable present in a container.
type EnvVar struct {
// Name of the environment variable.
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`

// Value of the environment variable.
Value string `json:"value"`
}
Comment thread
knechtionscoding marked this conversation as resolved.

// WorkspaceVolume defines an additional volume to mount into the agent
// container (and setup containers, once supported).
// container and setup containers.
type WorkspaceVolume struct {
// Name is the volume name (must be unique across workspace volumes).
// +kubebuilder:validation:MinLength=1
Expand Down Expand Up @@ -88,6 +119,15 @@ type WorkspaceSpec struct {
// +kubebuilder:validation:XValidation:rule="self.map(v, v.name).size() == self.size()",message="volume names must be unique"
// +kubebuilder:validation:XValidation:rule="self.all(v, v.name != 'workspace' && v.name != 'kelos-plugin')",message="volume names 'workspace' and 'kelos-plugin' are reserved"
Volumes []WorkspaceVolume `json:"volumes,omitempty"`

// Setup are init containers that run after git clone (and file injection)
// but before the agent container starts. Each container receives the
// workspace volume and any user-defined volumes. Use this for dependency
// installation, code generation, or other pre-agent setup steps.
// +optional
// +kubebuilder:validation:XValidation:rule="self.map(sc, sc.name).size() == self.size()",message="setup container names must be unique"
// +kubebuilder:validation:XValidation:rule="self.all(sc, !['git-clone','remote-setup','branch-setup','workspace-files','plugin-setup','skills-install'].exists(r, r == sc.name))",message="setup container names 'git-clone', 'remote-setup', 'branch-setup', 'workspace-files', 'plugin-setup', and 'skills-install' are reserved"
Setup []SetupContainer `json:"setup,omitempty"`
Comment thread
knechtionscoding marked this conversation as resolved.
}

// +genclient
Expand Down
47 changes: 47 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 33 additions & 1 deletion internal/controller/job_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,15 +495,47 @@ func (b *JobBuilder) buildAgentJob(task *kelosv1alpha1.Task, workspace *kelosv1a
mainContainer.VolumeMounts = []corev1.VolumeMount{volumeMount}

// Append user-defined workspace volumes to the pod and agent container.
var userVolumeMounts []corev1.VolumeMount
for _, wv := range workspace.Volumes {
volumes = append(volumes, corev1.Volume{
Name: wv.Name,
VolumeSource: wv.Source,
})
mainContainer.VolumeMounts = append(mainContainer.VolumeMounts, corev1.VolumeMount{
vm := corev1.VolumeMount{
Name: wv.Name,
MountPath: wv.MountPath,
ReadOnly: wv.ReadOnly,
}
userVolumeMounts = append(userVolumeMounts, vm)
mainContainer.VolumeMounts = append(mainContainer.VolumeMounts, vm)
}

// Append user-defined setup init containers. They run after git clone
// and file injection but before the agent, and receive both the workspace
// volume and any user-defined volumes.
for _, sc := range workspace.Setup {
mounts := make([]corev1.VolumeMount, 0, 1+len(userVolumeMounts))
mounts = append(mounts, volumeMount)
mounts = append(mounts, userVolumeMounts...)

var setupEnvVars []corev1.EnvVar
for _, e := range sc.Env {
setupEnvVars = append(setupEnvVars, corev1.EnvVar{
Name: e.Name,
Value: e.Value,
})
}

initContainers = append(initContainers, corev1.Container{
Name: sc.Name,
Image: sc.Image,
Command: sc.Command,
Env: setupEnvVars,
VolumeMounts: mounts,
WorkingDir: WorkspaceMountPath + "/repo",
SecurityContext: &corev1.SecurityContext{
RunAsUser: &agentUID,
},
})
}

Expand Down
Loading
Loading