feat(jar): add OCI registry pull for JAR artifacts with backward compat

- Add jarRef and jarPullSecret fields to FlinkJob CRD (jarUri/basicAuth deprecated)
- OCI pull via go-containerregistry with dual auth (K8s pull secret + env vars)
- Media type validation on pulled layers
- Atomic status patches with runningJarRef/runningJarDigest tracking
- NeedsUpgrade/RunningRef/RunningRefPatchData domain helpers
- README with usage guide, pushing JARs, and GitHub Actions CI/CD workflow
- CONTEXT.md domain glossary
This commit is contained in:
2026-07-24 17:37:30 +03:30
parent 91c10c89da
commit a36e72877d
15 changed files with 750 additions and 92 deletions

View File

@@ -60,16 +60,22 @@ func (a Args) MarshalJSON() ([]byte, error) {
}
type FlinkJobSpec struct {
Key string `json:"key"`
Name string `json:"name"`
FlinkCluster string `json:"flinkCluster"`
Parallelism int `json:"parallelism"`
JarURI string `json:"jarUri"`
JarURIBasicAuthUsername *string `json:"jarURIBasicAuthUsername"`
JarURIBasicAuthPassword *string `json:"jarURIBasicAuthPassword"`
SavepointInterval metaV1.Duration `json:"savepointInterval"`
EntryClass string `json:"entryClass"`
Args Args `json:"args,omitempty"`
Key string `json:"key"`
Name string `json:"name"`
FlinkCluster string `json:"flinkCluster"`
Parallelism int `json:"parallelism"`
JarRef string `json:"jarRef,omitempty"`
JarPullSecret string `json:"jarPullSecret,omitempty"`
SavepointInterval metaV1.Duration `json:"savepointInterval"`
EntryClass string `json:"entryClass"`
Args Args `json:"args,omitempty"`
// Deprecated: use JarRef instead. Kept for backward compatibility.
JarURI string `json:"jarUri,omitempty"`
// Deprecated: use JarPullSecret instead. Kept for backward compatibility.
JarURIBasicAuthUsername *string `json:"jarURIBasicAuthUsername,omitempty"`
// Deprecated: use JarPullSecret instead. Kept for backward compatibility.
JarURIBasicAuthPassword *string `json:"jarURIBasicAuthPassword,omitempty"`
}
type FlinkJobStatus struct {
@@ -85,7 +91,10 @@ type FlinkJobStatus struct {
LastRestoredSavepointDate *time.Time `json:"lastRestoredSavepointDate,omitempty"`
LastRestoredSavepointRestoredDate *time.Time `json:"lastRestoredSavepointRestoredDate,omitempty"`
RestoredCount int `json:"restoredCount,omitempty"`
RunningJarURI *string `json:"runningJarURI"`
RunningJarDigest *string `json:"runningJarDigest,omitempty"`
RunningJarRef *string `json:"runningJarRef,omitempty"`
// Deprecated: kept for backward compatibility during migration.
RunningJarURI *string `json:"runningJarURI,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -140,3 +149,48 @@ const (
LifeCycleStatusHealthy LifeCycleStatus = "HEALTHY"
LifeCycleStatusFailed LifeCycleStatus = "FAILED"
)
// EffectiveJarRef returns the OCI reference, preferring JarRef over the deprecated JarURI.
func (s *FlinkJobSpec) EffectiveJarRef() string {
if s.JarRef != "" {
return s.JarRef
}
return s.JarURI
}
// IsOCISource returns true if the job uses an OCI reference (jarRef) rather than an HTTP URL (jarUri).
func (s *FlinkJobSpec) IsOCISource() bool {
return s.JarRef != ""
}
// RunningRef returns the currently tracked running jar reference,
// preferring RunningJarRef (OCI) over the deprecated RunningJarURI.
func (st *FlinkJobStatus) RunningRef() string {
if st.RunningJarRef != nil {
return *st.RunningJarRef
}
if st.RunningJarURI != nil {
return *st.RunningJarURI
}
return ""
}
// NeedsUpgrade returns true if the spec's jar reference differs from
// what is currently running, indicating an upgrade is needed.
func (s *FlinkJobSpec) NeedsUpgrade(st FlinkJobStatus) bool {
running := st.RunningRef()
if running == "" {
return false
}
return s.EffectiveJarRef() != running
}
// RunningRefPatchKey returns the status patch key and value for tracking
// which jar reference is currently running.
func (s *FlinkJobSpec) RunningRefPatchData() (key string, value interface{}) {
if s.IsOCISource() {
ref := s.EffectiveJarRef()
return "runningJarRef", &ref
}
return "runningJarURI", s.JarURI
}