diff --git a/apis/training/v1alpha1/elasticdljob_types.go b/apis/training/v1alpha1/elasticdljob_types.go index 38170ebe..a8166294 100644 --- a/apis/training/v1alpha1/elasticdljob_types.go +++ b/apis/training/v1alpha1/elasticdljob_types.go @@ -35,6 +35,10 @@ type ElasticDLJobSpec struct { // "Master": ElasticDLReplicaSpec, // } ElasticDLReplicaSpecs map[common.ReplicaType]*common.ReplicaSpec `json:"elasticdlReplicaSpecs"` + + // GitSyncConfig defines the configuration for syncing code from Git repository + // +optional + GitSyncConfig *common.GitSyncOptions `json:"gitSyncConfig,omitempty"` } // +genclient diff --git a/apis/training/v1alpha1/marsjob_types.go b/apis/training/v1alpha1/marsjob_types.go index ebdda44d..a34a3661 100644 --- a/apis/training/v1alpha1/marsjob_types.go +++ b/apis/training/v1alpha1/marsjob_types.go @@ -40,6 +40,10 @@ type MarsJobSpec struct { // MarsReplicaSpecs is a map of MarsReplicaType(key) to ReplicaSpec(value), // specifying replicas and template of each type. MarsReplicaSpecs map[commonv1.ReplicaType]*commonv1.ReplicaSpec `json:"marsReplicaSpecs"` + + // GitSyncConfig defines the configuration for syncing code from Git repository + // +optional + GitSyncConfig *commonv1.GitSyncOptions `json:"gitSyncConfig,omitempty"` } // MarsJobStatus defines the observed state of MarsJob diff --git a/apis/training/v1alpha1/mpijob_types.go b/apis/training/v1alpha1/mpijob_types.go index 79ef7bb9..68ca05bd 100644 --- a/apis/training/v1alpha1/mpijob_types.go +++ b/apis/training/v1alpha1/mpijob_types.go @@ -46,6 +46,10 @@ type MPIJobSpec struct { // LegacySpec reserves the deprecated fields for backward compatibility. *MPIJobLegacySpec `json:",inline"` + + // GitSyncConfig defines the configuration for syncing code from Git repository + // +optional + GitSyncConfig *apiv1.GitSyncOptions `json:"gitSyncConfig,omitempty"` } // MPIJobLegacySpec is a collection of legacy fields that were used in v1alpha1/v1alpha2 but diff --git a/apis/training/v1alpha1/pytorchjob_types.go b/apis/training/v1alpha1/pytorchjob_types.go index 4b3f2787..806fda49 100644 --- a/apis/training/v1alpha1/pytorchjob_types.go +++ b/apis/training/v1alpha1/pytorchjob_types.go @@ -46,6 +46,10 @@ type PyTorchJobSpec struct { // CacheBackend is used to configure the cache engine for job // +optional CacheBackend *cachev1alpha1.CacheBackendSpec `json:"cacheBackend"` + + // GitSyncConfig defines the configuration for syncing code from Git repository + // +optional + GitSyncConfig *common.GitSyncOptions `json:"gitSyncConfig,omitempty"` } // PyTorchJobStatus defines the observed state of PyTorchJob diff --git a/apis/training/v1alpha1/tfjob_types.go b/apis/training/v1alpha1/tfjob_types.go index fd3d6b9c..da95845d 100644 --- a/apis/training/v1alpha1/tfjob_types.go +++ b/apis/training/v1alpha1/tfjob_types.go @@ -57,7 +57,7 @@ type TFJobSpec struct { // GitSyncConfig defines the configuration for syncing code from Git repository // +optional - GitSyncConfig string `json:"gitSyncConfig,omitempty"` + GitSyncConfig *commonv1.GitSyncOptions `json:"gitSyncConfig,omitempty"` } // +genclient diff --git a/apis/training/v1alpha1/xdljob_types.go b/apis/training/v1alpha1/xdljob_types.go index fe5de381..6eb06b9e 100644 --- a/apis/training/v1alpha1/xdljob_types.go +++ b/apis/training/v1alpha1/xdljob_types.go @@ -48,6 +48,10 @@ type XDLJobSpec struct { // MinFinishWorkPercentage takes precedence over MinFinishWorkerNum if both are // specified. MinFinishWorkerPercentage *int32 `json:"minFinishWorkRate,omitempty"` + + // GitSyncConfig defines the configuration for syncing code from Git repository + // +optional + GitSyncConfig *v1.GitSyncOptions `json:"gitSyncConfig,omitempty"` } // XDLJobStatus defines the observed state of XDLJob diff --git a/apis/training/v1alpha1/xgboostjob_types.go b/apis/training/v1alpha1/xgboostjob_types.go index 08c9fe3e..dbe12c99 100644 --- a/apis/training/v1alpha1/xgboostjob_types.go +++ b/apis/training/v1alpha1/xgboostjob_types.go @@ -37,6 +37,10 @@ type XGBoostJobSpec struct { // "Worker": ReplicaSpec, // } XGBReplicaSpecs map[commonv1.ReplicaType]*commonv1.ReplicaSpec `json:"xgbReplicaSpecs"` + + // GitSyncConfig defines the configuration for syncing code from Git repository + // +optional + GitSyncConfig *commonv1.GitSyncOptions `json:"gitSyncConfig,omitempty"` } // XGBoostJobStatus defines the observed state of XGBoostJob diff --git a/config/crd/bases/training.kubedl.io_elasticdljobs.yaml b/config/crd/bases/training.kubedl.io_elasticdljobs.yaml index effd16fb..1487c574 100644 --- a/config/crd/bases/training.kubedl.io_elasticdljobs.yaml +++ b/config/crd/bases/training.kubedl.io_elasticdljobs.yaml @@ -3063,6 +3063,95 @@ spec: type: object type: object type: object + gitSyncConfig: + properties: + branch: + type: string + depth: + type: string + destPath: + type: string + envs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + maxFailures: + type: integer + password: + type: string + revision: + type: string + rootPath: + type: string + source: + type: string + ssh: + type: boolean + sshFile: + type: string + user: + type: string + required: + - source + type: object schedulingPolicy: properties: minAvailable: diff --git a/config/crd/bases/training.kubedl.io_marsjobs.yaml b/config/crd/bases/training.kubedl.io_marsjobs.yaml index 73fbf03c..e7f8b7c1 100644 --- a/config/crd/bases/training.kubedl.io_marsjobs.yaml +++ b/config/crd/bases/training.kubedl.io_marsjobs.yaml @@ -66,6 +66,95 @@ spec: required: - schedule type: object + gitSyncConfig: + properties: + branch: + type: string + depth: + type: string + destPath: + type: string + envs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + maxFailures: + type: integer + password: + type: string + revision: + type: string + rootPath: + type: string + source: + type: string + ssh: + type: boolean + sshFile: + type: string + user: + type: string + required: + - source + type: object marsReplicaSpecs: additionalProperties: properties: diff --git a/config/crd/bases/training.kubedl.io_mpijobs.yaml b/config/crd/bases/training.kubedl.io_mpijobs.yaml index 878a6b6c..68c75eed 100644 --- a/config/crd/bases/training.kubedl.io_mpijobs.yaml +++ b/config/crd/bases/training.kubedl.io_mpijobs.yaml @@ -66,6 +66,95 @@ spec: required: - schedule type: object + gitSyncConfig: + properties: + branch: + type: string + depth: + type: string + destPath: + type: string + envs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + maxFailures: + type: integer + password: + type: string + revision: + type: string + rootPath: + type: string + source: + type: string + ssh: + type: boolean + sshFile: + type: string + user: + type: string + required: + - source + type: object gpus: format: int32 type: integer diff --git a/config/crd/bases/training.kubedl.io_pytorchjobs.yaml b/config/crd/bases/training.kubedl.io_pytorchjobs.yaml index c12b7dda..8d6d2625 100644 --- a/config/crd/bases/training.kubedl.io_pytorchjobs.yaml +++ b/config/crd/bases/training.kubedl.io_pytorchjobs.yaml @@ -120,6 +120,95 @@ spec: required: - schedule type: object + gitSyncConfig: + properties: + branch: + type: string + depth: + type: string + destPath: + type: string + envs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + maxFailures: + type: integer + password: + type: string + revision: + type: string + rootPath: + type: string + source: + type: string + ssh: + type: boolean + sshFile: + type: string + user: + type: string + required: + - source + type: object modelVersion: properties: createdBy: diff --git a/config/crd/bases/training.kubedl.io_tfjobs.yaml b/config/crd/bases/training.kubedl.io_tfjobs.yaml index 38b72489..39b89f7b 100644 --- a/config/crd/bases/training.kubedl.io_tfjobs.yaml +++ b/config/crd/bases/training.kubedl.io_tfjobs.yaml @@ -120,6 +120,95 @@ spec: required: - schedule type: object + gitSyncConfig: + properties: + branch: + type: string + depth: + type: string + destPath: + type: string + envs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + maxFailures: + type: integer + password: + type: string + revision: + type: string + rootPath: + type: string + source: + type: string + ssh: + type: boolean + sshFile: + type: string + user: + type: string + required: + - source + type: object modelVersion: properties: createdBy: diff --git a/config/crd/bases/training.kubedl.io_xdljobs.yaml b/config/crd/bases/training.kubedl.io_xdljobs.yaml index ff3a405b..68ee1133 100644 --- a/config/crd/bases/training.kubedl.io_xdljobs.yaml +++ b/config/crd/bases/training.kubedl.io_xdljobs.yaml @@ -66,6 +66,95 @@ spec: required: - schedule type: object + gitSyncConfig: + properties: + branch: + type: string + depth: + type: string + destPath: + type: string + envs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + maxFailures: + type: integer + password: + type: string + revision: + type: string + rootPath: + type: string + source: + type: string + ssh: + type: boolean + sshFile: + type: string + user: + type: string + required: + - source + type: object minFinishWorkNum: format: int32 type: integer diff --git a/config/crd/bases/training.kubedl.io_xgboostjobs.yaml b/config/crd/bases/training.kubedl.io_xgboostjobs.yaml index b248367b..3ff09376 100644 --- a/config/crd/bases/training.kubedl.io_xgboostjobs.yaml +++ b/config/crd/bases/training.kubedl.io_xgboostjobs.yaml @@ -66,6 +66,95 @@ spec: required: - schedule type: object + gitSyncConfig: + properties: + branch: + type: string + depth: + type: string + destPath: + type: string + envs: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + maxFailures: + type: integer + password: + type: string + revision: + type: string + rootPath: + type: string + source: + type: string + ssh: + type: boolean + sshFile: + type: string + user: + type: string + required: + - source + type: object schedulingPolicy: properties: minAvailable: diff --git a/pkg/code_sync/git_sync_handler.go b/pkg/code_sync/git_sync_handler.go index 6782a48f..5dcec36d 100644 --- a/pkg/code_sync/git_sync_handler.go +++ b/pkg/code_sync/git_sync_handler.go @@ -5,6 +5,7 @@ import ( "strconv" "strings" + commonv1 "github.com/alibaba/kubedl/pkg/job_controller/api/v1" v1 "k8s.io/api/core/v1" ) @@ -14,29 +15,10 @@ const ( var _ CodeSyncHandler = &gitSyncHandler{} -type gitSyncOptions struct { - SyncOptions `json:",inline"` - - // All fields down below are optional. - - // Git repository settings for user to specify. - Branch string `json:"branch,omitempty"` - Revision string `json:"revision,omitempty"` - Depth string `json:"depth,omitempty"` - // Max consecutive failures allowed. - MaxFailures int `json:"maxFailures,omitempty"` - // SSH settings for users to use git in ssh pattern. - SSH bool `json:"ssh,omitempty"` - SSHFile string `json:"sshFile,omitempty"` - // User-customized account settings. - User string `json:"user,omitempty"` - Password string `json:"password,omitempty"` -} - type gitSyncHandler struct{} func (h *gitSyncHandler) InitContainer(optsConfig []byte, mountVolume *v1.Volume) (*v1.Container, string, error) { - opts := gitSyncOptions{} + opts := commonv1.GitSyncOptions{} if err := json.Unmarshal(optsConfig, &opts); err != nil { return nil, "", err } @@ -59,7 +41,7 @@ func (h *gitSyncHandler) InitContainer(optsConfig []byte, mountVolume *v1.Volume return &container, opts.DestPath, nil } -func setDefaultSyncOpts(opts *gitSyncOptions) { +func setDefaultSyncOpts(opts *commonv1.GitSyncOptions) { if opts.RootPath == "" { opts.RootPath = DefaultCodeRootPath } @@ -79,7 +61,7 @@ func setDefaultSyncOpts(opts *gitSyncOptions) { } } -func setSyncOptsEnvs(opts *gitSyncOptions) { +func setSyncOptsEnvs(opts *commonv1.GitSyncOptions) { opts.Envs = append(opts.Envs, v1.EnvVar{ Name: "GIT_SYNC_REPO", Value: opts.Source, diff --git a/pkg/code_sync/sync_handler.go b/pkg/code_sync/sync_handler.go index 265e4b34..55dc378a 100644 --- a/pkg/code_sync/sync_handler.go +++ b/pkg/code_sync/sync_handler.go @@ -1,12 +1,12 @@ package code_sync import ( - trainingv1alpha1 "github.com/alibaba/kubedl/apis/training/v1alpha1" + "encoding/json" "path" apiv1 "github.com/alibaba/kubedl/pkg/job_controller/api/v1" + commonv1 "github.com/alibaba/kubedl/pkg/job_controller/api/v1" v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -17,32 +17,19 @@ type CodeSyncHandler interface { InitContainer(optsConfig []byte, mountVolume *v1.Volume) (c *v1.Container, codePath string, err error) } -type SyncOptions struct { - // Code source address.(required) - Source string `json:"source"` - // Image contains toolkits to execute syncing code. - Image string `json:"image,omitempty"` - // Code root/destination directory path. - // Root: the path to save downloaded files. - // Dest: the name of (a symlink to) a directory in which to check-out files - RootPath string `json:"rootPath,omitempty"` - DestPath string `json:"destPath,omitempty"` - // User-customized environment variables. - Envs []v1.EnvVar `json:"envs,omitempty"` -} - -func InjectCodeSyncInitContainers(metaObj metav1.Object, specs map[apiv1.ReplicaType]*apiv1.ReplicaSpec) error { - var err error - - if cfg := metaObj.(*trainingv1alpha1.TFJob).Spec.GitSyncConfig; cfg != "" { - if err = injectCodeSyncInitContainer([]byte(cfg), &gitSyncHandler{}, specs, &v1.Volume{ +func InjectCodeSyncInitContainers(specs map[apiv1.ReplicaType]*apiv1.ReplicaSpec, gitSyncConfig *commonv1.GitSyncOptions) error { + if cfg := gitSyncConfig; cfg != nil { + optsConfig, err := json.Marshal(gitSyncConfig) + if err != nil { + return err + } + if err = injectCodeSyncInitContainer(optsConfig, &gitSyncHandler{}, specs, &v1.Volume{ Name: "git-sync", VolumeSource: v1.VolumeSource{EmptyDir: &v1.EmptyDirVolumeSource{}}, }); err != nil { return err } } - // TODO(SimonCqk): support other sources. return nil diff --git a/pkg/job_controller/api/v1/types.go b/pkg/job_controller/api/v1/types.go index 2ac1acb7..13758570 100644 --- a/pkg/job_controller/api/v1/types.go +++ b/pkg/job_controller/api/v1/types.go @@ -312,3 +312,36 @@ type DAGCondition struct { // OnPhase defines at which phase the upstream replica will trigger this condition. OnPhase v1.PodPhase `json:"onPhase"` } + +type SyncOptions struct { + // Code source address.(required) + Source string `json:"source"` + // Image contains toolkits to execute syncing code. + Image string `json:"image,omitempty"` + // Code root/destination directory path. + // Root: the path to save downloaded files. + // Dest: the name of (a symlink to) a directory in which to check-out files + RootPath string `json:"rootPath,omitempty"` + DestPath string `json:"destPath,omitempty"` + // User-customized environment variables. + Envs []v1.EnvVar `json:"envs,omitempty"` +} + +type GitSyncOptions struct { + SyncOptions `json:",inline"` + + // All fields down below are optional. + + // Git repository settings for user to specify. + Branch string `json:"branch,omitempty"` + Revision string `json:"revision,omitempty"` + Depth string `json:"depth,omitempty"` + // Max consecutive failures allowed. + MaxFailures int `json:"maxFailures,omitempty"` + // SSH settings for users to use git in ssh pattern. + SSH bool `json:"ssh,omitempty"` + SSHFile string `json:"sshFile,omitempty"` + // User-customized account settings. + User string `json:"user,omitempty"` + Password string `json:"password,omitempty"` +}