|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- package globalmanager
-
- import (
- "context"
- "strings"
-
- v1 "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/labels"
- "k8s.io/apimachinery/pkg/util/intstr"
- "k8s.io/client-go/kubernetes"
- "k8s.io/klog/v2"
- k8scontroller "k8s.io/kubernetes/pkg/controller"
- )
-
- type WorkerMount struct {
- Name string
- // the url to be mounted
- URL *MountURL
-
- // for some cases, there are more than one url to be mounted
- URLs []MountURL
-
- // envName indicates the environment key of the mounts injected to the worker
- EnvName string
- }
-
- // WorkerParam describes the system-defined parameters of worker
- type WorkerParam struct {
- mounts []WorkerMount
-
- env map[string]string
- workerType string
-
- // if true, force to use hostNetwork
- hostNetwork bool
-
- restartPolicy v1.RestartPolicy
- }
-
- // generateLabels generates labels for an object
- func generateLabels(object CommonInterface, workerType string) map[string]string {
- kind := object.GroupVersionKind().Kind
- group := object.GroupVersionKind().Group
-
- keyPrefix := strings.ToLower(kind + "." + group + "/")
-
- labels := make(map[string]string)
- labels[keyPrefix+"name"] = object.GetName()
- labels[keyPrefix+"uid"] = string(object.GetUID())
- if workerType != "" {
- labels[keyPrefix+"worker-type"] = strings.ToLower(workerType)
- }
- return labels
- }
-
- // GenerateSelector generates the selector of an object for worker
- func GenerateSelector(object CommonInterface) (labels.Selector, error) {
- ls := &metav1.LabelSelector{
- // select any type workers
- MatchLabels: generateLabels(object, ""),
- }
- return metav1.LabelSelectorAsSelector(ls)
- }
-
- // CreateKubernetesService creates a k8s service for an object given ip and port
- func CreateKubernetesService(kubeClient kubernetes.Interface, object CommonInterface, workerType string, inputPort int32, inputIP string) (int32, error) {
- ctx := context.Background()
- name := object.GetName()
- namespace := object.GetNamespace()
- kind := object.GroupVersionKind().Kind
- targePort := intstr.IntOrString{
- IntVal: inputPort,
- }
- serviceSpec := &v1.Service{
- ObjectMeta: metav1.ObjectMeta{
- Namespace: object.GetNamespace(),
- GenerateName: name + "-" + "service" + "-",
- OwnerReferences: []metav1.OwnerReference{
- *metav1.NewControllerRef(object, object.GroupVersionKind()),
- },
- Labels: generateLabels(object, workerType),
- },
- Spec: v1.ServiceSpec{
- Selector: generateLabels(object, workerType),
- ExternalIPs: []string{
- inputIP,
- },
- Type: v1.ServiceTypeNodePort,
- Ports: []v1.ServicePort{
- {
- Port: inputPort,
- TargetPort: targePort,
- },
- },
- },
- }
- service, err := kubeClient.CoreV1().Services(namespace).Create(ctx, serviceSpec, metav1.CreateOptions{})
- if err != nil {
- klog.Warningf("failed to create service for %v %v/%v, err:%s", kind, namespace, name, err)
- return 0, err
- }
-
- klog.V(2).Infof("Service %s is created successfully for %v %v/%v", service.Name, kind, namespace, name)
- return service.Spec.Ports[0].NodePort, nil
- }
-
- // injectWorkerParam modifies pod in-place
- func injectWorkerParam(pod *v1.Pod, workerParam *WorkerParam, object CommonInterface) {
- InjectStorageInitializer(pod, workerParam)
-
- envs := createEnvVars(workerParam.env)
- for idx := range pod.Spec.Containers {
- pod.Spec.Containers[idx].Env = append(
- pod.Spec.Containers[idx].Env, envs...,
- )
- }
-
- // inject our labels
- if pod.Labels == nil {
- pod.Labels = make(map[string]string)
- }
-
- for k, v := range generateLabels(object, workerParam.workerType) {
- pod.Labels[k] = v
- }
-
- pod.GenerateName = object.GetName() + "-" + strings.ToLower(workerParam.workerType) + "-"
-
- pod.Namespace = object.GetNamespace()
-
- if workerParam.hostNetwork {
- // FIXME
- // force to set hostnetwork
- pod.Spec.HostNetwork = true
- }
-
- if pod.Spec.RestartPolicy == "" {
- pod.Spec.RestartPolicy = workerParam.restartPolicy
- }
- }
-
- // createPodWithTemplate creates and returns a pod object given a crd object, pod template, and workerParam
- func createPodWithTemplate(client kubernetes.Interface, object CommonInterface, spec *v1.PodTemplateSpec, workerParam *WorkerParam) (*v1.Pod, error) {
- objectKind := object.GroupVersionKind()
- pod, _ := k8scontroller.GetPodFromTemplate(spec, object, metav1.NewControllerRef(object, objectKind))
- injectWorkerParam(pod, workerParam, object)
-
- createdPod, err := client.CoreV1().Pods(object.GetNamespace()).Create(context.TODO(), pod, metav1.CreateOptions{})
- objectName := object.GetNamespace() + "/" + object.GetName()
- if err != nil {
- klog.Warningf("failed to create pod(type=%s) for %s %s, err:%s", workerParam.workerType, objectKind, objectName, err)
- return nil, err
- }
- klog.V(2).Infof("pod %s is created successfully for %s %s", createdPod.Name, objectKind, objectName)
- return createdPod, nil
- }
-
- // createEnvVars creates EnvMap for container
- // include EnvName and EnvValue map for stage of creating a pod
- func createEnvVars(envMap map[string]string) []v1.EnvVar {
- var envVars []v1.EnvVar
- for envName, envValue := range envMap {
- Env := v1.EnvVar{
- Name: envName,
- Value: envValue,
- }
- envVars = append(envVars, Env)
- }
- return envVars
- }
|