Skip to content

Commit

Permalink
chore: enable datastore controller
Browse files Browse the repository at this point in the history
Signed-off-by: shil <[email protected]>
  • Loading branch information
shil committed Nov 25, 2024
1 parent b6f5570 commit 3ed26de
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 45 deletions.
125 changes: 115 additions & 10 deletions api/apps/v1alpha1/nemo_datastore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@ import (
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

const (
// NemoDatastoreConditionReady indicates that the NEMO GuardrailService is ready.
// NemoDatastoreConditionReady indicates that the NEMO datastore service is ready.
NemoDatastoreConditionReady = "Ready"
// NemoDatastoreConditionFailed indicates that the NEMO GuardrailService has failed.
// NemoDatastoreConditionFailed indicates that the NEMO datastore service has failed.
NemoDatastoreConditionFailed = "Failed"

// NemoDatastoreStatusPending indicates that NEMO GuardrailService is in pending state
// NemoDatastoreStatusPending indicates that NEMO datastore service is in pending state
NemoDatastoreStatusPending = "Pending"
// NemoDatastoreStatusNotReady indicates that NEMO GuardrailService is not ready
// NemoDatastoreStatusNotReady indicates that NEMO datastore service is not ready
NemoDatastoreStatusNotReady = "NotReady"
// NemoDatastoreStatusReady indicates that NEMO GuardrailService is ready
// NemoDatastoreStatusReady indicates that NEMO datastore service is ready
NemoDatastoreStatusReady = "Ready"
// NemoDatastoreStatusFailed indicates that NEMO GuardrailService has failed
// NemoDatastoreStatusFailed indicates that NEMO datastore service has failed
NemoDatastoreStatusFailed = "Failed"
)

Expand All @@ -58,7 +58,7 @@ type NemoDatastoreSpec struct {
Args []string `json:"args,omitempty"`
Env []corev1.EnvVar `json:"env,omitempty"`
// The name of an secret that contains authn for the NGC NIM service API
AuthSecret string `json:"authSecret"`
AuthSecret string `json:"authSecret"`
Labels map[string]string `json:"labels,omitempty"`
Annotations map[string]string `json:"annotations,omitempty"`
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
Expand All @@ -78,6 +78,7 @@ type NemoDatastoreSpec struct {
GroupID *int64 `json:"groupID,omitempty"`
RuntimeClass string `json:"runtimeClass,omitempty"`

DataStoreParams NemoDataStoreParams `json:"dataStoreParams"`
}

// NemoDatastoreStatus defines the observed state of NemoDatastore
Expand All @@ -87,6 +88,22 @@ type NemoDatastoreStatus struct {
State string `json:"state,omitempty"`
}

type NemoDataStoreParams struct {
AppVersion string `json:"appVersion"`
GiteaEndpoint string `json:"giteaEndpoint"`
GiteaSecret string `json:"giteaSecret"`
DatabaseURL string `json:"databaseURL"`
DatabaseHost string `json:"databaseHost"`
DatabasePort string `json:"databasePort"`
DBSecret string `json:"dbSecret"`

EnvConfigMap string `json:"envConfigmap"`
EnvSecret string `json:"envSecret"`

InitContainerImage string `json:"initContainerImage,omitempty"`
InitContainerCommand []string `json:"initContainerCommand,omitempty"`
}

// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
Expand Down Expand Up @@ -124,7 +141,8 @@ func (n *NemoDatastore) GetPVCName(pvc PersistentVolumeClaim) string {
// GetStandardSelectorLabels returns the standard selector labels for the NemoDatastore deployment
func (n *NemoDatastore) GetStandardSelectorLabels() map[string]string {
return map[string]string{
"app": n.Name,
"app.kubernetes.io/name": n.Name,
"app.kubernetes.io/instance": n.Name,
}
}

Expand All @@ -142,11 +160,98 @@ func (n *NemoDatastore) GetStandardLabels() map[string]string {
// GetStandardEnv returns the standard set of env variables for the NemoDatastore container
func (n *NemoDatastore) GetStandardEnv() []corev1.EnvVar {
// add standard env required for NIM service
envVars := []corev1.EnvVar{}

envVars := []corev1.EnvVar{
{
Name: "APP_VERSION",
Value: n.Spec.DataStoreParams.AppVersion,
},
{
Name: "GITEA_ENDPOINT",
Value: n.Spec.DataStoreParams.GiteaEndpoint,
},
{
Name: "GITEA_ORG_NAME",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "username",
LocalObjectReference: corev1.LocalObjectReference{
Name: n.Spec.DataStoreParams.GiteaSecret,
},
},
},
},
{
Name: "GITEA_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "password",
LocalObjectReference: corev1.LocalObjectReference{
Name: n.Spec.DataStoreParams.GiteaSecret,
},
},
},
},
{
Name: "DATABASE_URL",
Value: n.Spec.DataStoreParams.DatabaseURL,
},
{
Name: "DB_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "password",
LocalObjectReference: corev1.LocalObjectReference{
Name: n.Spec.DataStoreParams.DBSecret,
},
},
},
},
}
return envVars
}

// GetStandardAnnotations returns default annotations to apply to the NemoDatastore instance
func (n *NemoDatastore) GetEnvFrom() []corev1.EnvFromSource {
return []corev1.EnvFromSource{
{
ConfigMapRef: &corev1.ConfigMapEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: n.Spec.DataStoreParams.EnvConfigMap,
},
},
},
{
SecretRef: &corev1.SecretEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: n.Spec.DataStoreParams.EnvSecret,
},
},
},
}
}

func (n *NemoDatastore) GetInitContainers() []corev1.Container {
image := n.Spec.DataStoreParams.InitContainerImage
if image == "" {
image = "busybox"
}
cmd := n.Spec.DataStoreParams.InitContainerCommand
if len(cmd) == 0 {
cmd = []string{
"sh",
"-c",
fmt.Sprintf("until nc -z %s %s; do echo \"PostgreSQL is unavailable. Sleeping for 5 seconds\"; sleep 5; done;", n.Spec.DataStoreParams.DatabaseHost, n.Spec.DataStoreParams.DatabasePort),
}
}
return []corev1.Container{
{
Name: "wait-postgres-ready",
Image: image,
Command: cmd,
},
}
}

// GetStandardAnnotations returns default annotations to apply to the NemoDatastore instance
func (n *NemoDatastore) GetStandardAnnotations() map[string]string {
standardAnnotations := map[string]string{
Expand Down
4 changes: 3 additions & 1 deletion api/apps/v1alpha1/nemo_guardrails_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ func (n *NemoGuardrail) GetPVCName(pvc PersistentVolumeClaim) string {
// GetStandardSelectorLabels returns the standard selector labels for the NemoGuardrail deployment
func (n *NemoGuardrail) GetStandardSelectorLabels() map[string]string {
return map[string]string{
"app": n.Name,
"app": n.Name,
"app.kubernetes.io/name": n.Name,
"app.kubernetes.io/instance": n.Name,
}
}

Expand Down
21 changes: 21 additions & 0 deletions api/apps/v1alpha1/zz_generated.deepcopy.go

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

11 changes: 11 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,17 @@ func main() {
os.Exit(1)
}

if err = controller.NewNemoDatastoreReconciler(
mgr.GetClient(),
mgr.GetScheme(),
updater,
render.NewRenderer("/manifests"),
ctrl.Log.WithName("controllers").WithName("NemoDatastore"),
).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "NemoDatastore")
os.Exit(1)
}

// +kubebuilder:scaffold:builder

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
Expand Down
63 changes: 35 additions & 28 deletions config/crd/bases/apps.nvidia.com_nemodatastores.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,36 +63,42 @@ spec:
items:
type: string
type: array
configStore:
description: ConfigStore stores the config of the guardrail service
dataStoreParams:
properties:
configMap:
appVersion:
type: string
pvc:
description: PersistentVolumeClaim defines the attributes of PVC
used as a source for caching NIM model
properties:
create:
description: Create indicates to create a new PVC
type: boolean
name:
description: Name is the name of the PVC
type: string
size:
description: Size of the NIM cache in Gi, used during PVC
creation
type: string
storageClass:
description: StorageClass to be used for PVC creation. Leave
it as empty if the PVC is already created.
type: string
subPath:
type: string
volumeAccessMode:
description: VolumeAccessMode is the volume access mode of
the PVC
type: string
type: object
databaseHost:
type: string
databasePort:
type: string
databaseURL:
type: string
dbSecret:
type: string
envConfigmap:
type: string
envSecret:
type: string
giteaEndpoint:
type: string
giteaSecret:
type: string
initContainerCommand:
items:
type: string
type: array
initContainerImage:
type: string
required:
- appVersion
- databaseHost
- databasePort
- databaseURL
- dbSecret
- envConfigmap
- envSecret
- giteaEndpoint
- giteaSecret
type: object
env:
items:
Expand Down Expand Up @@ -2130,6 +2136,7 @@ spec:
type: integer
required:
- authSecret
- dataStoreParams
type: object
status:
description: NemoDatastoreStatus defines the observed state of NemoDatastore
Expand Down
3 changes: 3 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ rules:
- apiGroups:
- apps.nvidia.com
resources:
- nemodatastores
- nemoguardrails
- nimcaches
- nimpipelines
Expand All @@ -77,6 +78,7 @@ rules:
- apiGroups:
- apps.nvidia.com
resources:
- nemodatastores/finalizers
- nemoguardrails/finalizers
- nimcaches/finalizers
- nimpipelines/finalizers
Expand All @@ -86,6 +88,7 @@ rules:
- apiGroups:
- apps.nvidia.com
resources:
- nemodatastores/status
- nemoguardrails/status
- nimcaches/status
- nimpipelines/status
Expand Down
23 changes: 17 additions & 6 deletions internal/controller/nemo_datastore_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,9 @@ func NewNemoDatastoreReconciler(client client.Client, scheme *runtime.Scheme, up
}
}

// +kubebuilder:rbac:groups=apps.nvidia.com,resources=nemoguardrails,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=apps.nvidia.com,resources=nemoguardrails/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=apps.nvidia.com,resources=nemoguardrails/finalizers,verbs=update
// +kubebuilder:rbac:groups=apps.nvidia.com,resources=nimcaches,verbs=get;list;watch;
// +kubebuilder:rbac:groups=apps.nvidia.com,resources=nemodatastores,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=apps.nvidia.com,resources=nemodatastores/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=apps.nvidia.com,resources=nemodatastores/finalizers,verbs=update
// +kubebuilder:rbac:groups=config.openshift.io,resources=clusterversions;proxies,verbs=get;list;watch
// +kubebuilder:rbac:groups=security.openshift.io,resources=securitycontextconstraints,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=security.openshift.io,resources=securitycontextconstraints,verbs=use,resourceNames=nonroot
Expand Down Expand Up @@ -222,7 +221,7 @@ func (r *NemoDatastoreReconciler) GetOrchestratorType() (k8sutil.OrchestratorTyp

// SetupWithManager sets up the controller with the Manager.
func (r *NemoDatastoreReconciler) SetupWithManager(mgr ctrl.Manager) error {
r.recorder = mgr.GetEventRecorderFor("nemo-guardrail-service-controller")
r.recorder = mgr.GetEventRecorderFor("nemo-datastore-service-controller")
return ctrl.NewControllerManagedBy(mgr).
For(&appsv1alpha1.NemoDatastore{}).
Owns(&appsv1.Deployment{}).
Expand Down Expand Up @@ -364,7 +363,19 @@ func (r *NemoDatastoreReconciler) reconcileNemoDatastore(ctx context.Context, ne

// Sync deployment
err = r.renderAndSyncResource(ctx, nemoDatastore, &renderer, &appsv1.Deployment{}, func() (client.Object, error) {
return renderer.Deployment(deploymentParams)
result, err := renderer.Deployment(deploymentParams)
if err != nil {
return nil, err
}
initContainers := nemoDatastore.GetInitContainers()
if len(initContainers) > 0 {
result.Spec.Template.Spec.InitContainers = initContainers
}
envFrom := nemoDatastore.GetEnvFrom()
if len(envFrom) > 0 {
result.Spec.Template.Spec.Containers[0].EnvFrom = envFrom
}
return result, nil
}, "deployment", conditions.ReasonDeploymentFailed)
if err != nil {
return ctrl.Result{}, err
Expand Down

0 comments on commit 3ed26de

Please sign in to comment.